前言
关于用Rsa 非对称算法进行加解密,处了常规的生成公私钥密钥对外,还有一种方式就是通过指数与模的形式取得公钥或者私钥对象,从而进行加解密计算。
常用加解密情形
android端和服务端是如何使用指数和模进行数据的加解密?
主要有以下几种形式:
A.服务端根据客户端的特殊请求(可以是双方规定的请求每天第一次请求之类的动作)随机动态生成一组加密的公私钥的指数和模,并且将公钥或者私钥的指数和模通过加密的方式传递给客户端(可以是3des-cbc或者其他可靠的加密方式,保障秘钥信息的安全性)。然后客户端每次通讯都用解密后端公钥或者私钥对象进行加解密服务端的数据。
以上所述的场景一般都是用在银联pos端下发主秘钥的情形。
主要流程如下:
其中1,2个步奏是关键,部分公司 采用的方式都是客户端生成8*N字节的随机数上传给服务端生成公私钥对,客户端就行3des或者des 的cbc模式界面,具体看服务端和客户端的协议
B.请各位补充..........
遇到的坑
当然今天讲的并不是以上的知识点,在这边记录下遇到的坑给那些受到伤害的同行一些参考。
坑:
1.指数和模(这个是16进制的)获取错误。
2.填充方式错误,除了常见的rsa填充还有其他的填充方式,例如:
代码示例
获取公钥对象或者是私有对象,这边代码显示的是获取公钥对象
public static RSAPublicKey getPublicKey(String modulus, String exponent) {
try {
BigInteger b1 = new BigInteger(modulus, 16); //此处为16进制数,模
BigInteger b2 = new BigInteger(exponent, 16); //此处为16进制数,指数
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(b1, b2);
return (RSAPublicKey) keyFactory.generatePublic(keySpec);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
公钥解密方式
//加密填充方式,列举常用的3种
public static final String KEY_ALGORITHM = "RSA";
public static final String ECB_PKCS1_PADDING = "RSA/ECB/PKCS1Padding";
public static final String TRANSFORMATION = "RSA/ECB/NoPadding";
public static String decryptByPublicKey(String data, String modules, String component)
throws Exception {
RSAPublicKey pubKey = RSAUtils.getPublicKey(modules, component);
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.DECRYPT_MODE, pubKey);
byte[] b = cipher.doFinal(Convert.str2Bcd(data));
return Convert.bcd2Str(mainkey);
}
遇到的坑主要是这边的填充方式填充错误,由于某种原因服务端的填充方式获取不到,所以只能一个个测试过去。填充方式也是寻求帮助后才找到的,希望对大家有用。
工具类bcd2Str代码(16进制字节数组转字符串)
public static String bcd2Str(byte[] b) {
char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
StringBuilder sb = new StringBuilder(b.length * 2);
for (int i = 0; i < b.length; ++i) {
sb.append(HEX_DIGITS[((b[i] & 0xF0) >>> 4)]);
sb.append(HEX_DIGITS[(b[i] & 0xF)]);
}
return sb.toString();
}