我正在使用RSA加密的Android应用程序。
我可以从我的服务器,私钥和朋友公钥中获取。
私钥是这样的:
{"n":"...","d":"...","p":"...","q":"...","dmp1":"...","dmq1":"...","coeff":"..."} (jsbn json format)
modulus => n
public exponent => e
private exponent => d
prime1 => p
prime2 => q
exponent1 => dmp1
exponent2 => dmq1
coefficient => coeff
使用此密钥,我需要解密从我的服务器收到的消息,并且已经通过javascript库(SJCL)加密。 我还需要加密消息,以便能够使用javascrypt库对其进行解密。
现在我已经这样做了:
public static String decrypt (String data, String stringKey) throws Exception {
JSONObject jsonKey = new JSONObject(stringKey);
BigInteger n = new BigInteger(Base64.decode(jsonKey.getString("n"), Base64.DEFAULT));
BigInteger e = new BigInteger("10001");
BigInteger d = new BigInteger(Base64.decode(jsonKey.getString("d"), Base64.DEFAULT));
BigInteger p = new BigInteger(Base64.decode(jsonKey.getString("p"), Base64.DEFAULT));
BigInteger q = new BigInteger(Base64.decode(jsonKey.getString("q"), Base64.DEFAULT));
BigInteger dmp1 = new BigInteger(Base64.decode(jsonKey.getString("dmp1"), Base64.DEFAULT));
BigInteger dmq1 = new BigInteger(Base64.decode(jsonKey.getString("dmq1"), Base64.DEFAULT));
BigInteger coeff = new BigInteger(Base64.decode(jsonKey.getString("coeff"), Base64.DEFAULT));
KeySpec privateKeySpec = new RSAPrivateCrtKeySpec(n, e, d, p, q, dmp1, dmq1, coeff);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);
Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] dec = cipher.doFinal(data.getBytes());
return new String(Base64.decode(dec, Base64.DEFAULT));
}
现在我明白了:
javax.crypto.IllegalBlockSizeException:输入必须小于96个字节
答案 0 :(得分:0)
PrivateKey.getEncoded()返回根据PKCS#1标准编码的ASN.1二进制文件。
答案 1 :(得分:0)
花了大量时间在另一个项目上后,我回到了这个应用程序,并解决了我的问题。
首先,SJCL / JSBN库生成的私钥json是hexa字符串。 所以我只需要在字节数组中转换我的字符串。
BigInteger n = new BigInteger(Utils.hexStringToByteArray(nString));
BigInteger e = new BigInteger("10001", 16); // Public exponent
发送的加密数据也是一个六进制字符串。
byte[] dec = cipher.doFinal(Utils.hexStringToByteArray(data));
return new String(dec, "UTF-8");
密码将字节数组作为明文返回。
算法:
Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding");
和hexStringToByteArray函数:
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len/2];
s = s.toUpperCase();
for(int i = 0; i < len; i+=2){
data[i/2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i+1), 16));
}
return data;
}
public static String byteArrayToHexString(byte[] bytes) {
char[] hexChars = new char[bytes.length*2];
int v;
for(int j=0; j < bytes.length; j++) {
v = bytes[j] & 0xFF;
hexChars[j*2] = hexArray[v>>>4];
hexChars[j*2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars).toLowerCase();
}
当我查看错误的地方时,将我的BigInteger解码为base64编码字符串。