1.RSA介绍
RSA是一种常用的非对称加密算法,所谓非对称加密是指使用一对密钥(公钥和私钥)进行加密和解密,公钥人人都可以获得,用于加密数据,私钥保存在服务器中,用于解密数据。
2. 在Android中使用RSA
Java中已内置RSA支持,示例代码如下:
2.1 从字符串加载公钥
public static RSAPublicKey getPublicKey(String publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
//通过X509编码的Key指令获得公钥对象
KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(android.util.Base64.decode(publicKey.getBytes(), android.util.Base64.URL_SAFE));
RSAPublicKey key = (RSAPublicKey) keyFactory.generatePublic(x509KeySpec);
return key;
}
这里是用安卓自带的Base64加密解密。必须注意加密解密的第二个参数必须选成android.util.Base64.URL_SAFE。Default会报错 公钥非法。
2.2 RSA加密数据
public static String publicEncrypt(String data, RSAPublicKey publicKey) {
try {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return android.util.Base64.encodeToString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET), publicKey.getModulus().bitLength()), android.util.Base64.URL_SAFE);
} catch (Exception e) {
throw new RuntimeException("加密字符串[" + data + "]时遇到异常", e);
}
}
private static byte[] rsaSplitCodec(Cipher cipher, int opmode, byte[] datas, int keySize) {
int maxBlock = 0;
if (opmode == Cipher.DECRYPT_MODE) {
maxBlock = keySize / 8;
} else {
maxBlock = keySize / 8 - 11;
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] buff;
int i = 0;
try {
while (datas.length > offSet) {
if (datas.length - offSet > maxBlock) {
buff = cipher.doFinal(datas, offSet, maxBlock);
} else {
buff = cipher.doFinal(datas, offSet, datas.length - offSet);
}
out.write(buff, 0, buff.length);
i++;
offSet = i * maxBlock;
}
} catch (Exception e) {
throw new RuntimeException("加解密阀值为[" + maxBlock + "]的数据时发生异常", e);
}
byte[] resultDatas = out.toByteArray();
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
return resultDatas;
}
这里注意用于加密时的Cipher,创建的参数不要写成只带”RSA”的:
Cipher cipher = Cipher.getInstance("RSA");
应为这种的
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
最后不要忘了将参数用Base64编码
param = URLEncoder.encode((String)param,"utf-8");
3.发送数据到后台
最后只需要讲用户名和加密的密码通过okhttp传到后台即可。
网友评论