用于加密的Node.js代码
function encrypt(msg) {
try {
const public_key = fs.readFileSync(path.join(__dirname, 'PublicKey.pem'), 'utf8');
const encryptStr = crypto.publicEncrypt({
key: public_key,
padding: crypto.constants.RSA_PKCS1_PADDING
}, Buffer.from(msg,'utf8'));
let encryptString = encryptStr.toString('hex');
return encryptString;
} catch (e) {
console.log(e);
return false;
}
}用于解密的Android代码
public static String decryptStringWithPrivateKey(String s, String keyFilename) throws Exception {
Cipher cipher = Cipher.getInstance("RSA");
PrivateKey pkey = readPrivateKeyFromPem(keyFilename);
cipher.init(Cipher.DECRYPT_MODE, pkey);
String dec = new String(cipher.doFinal(Base64.getDecoder().decode(s)), "UTF-8");
return dec;
}
public static PrivateKey readPrivateKeyFromPem(String keyFilename) throws Exception {
byte[] keyBytes = Files.readAllBytes(new File(keyFilename).toPath());
String keyString = new String(keyBytes);
if (keyString.contains("BEGIN PRIVATE KEY")) {
return readPrivateKeyFromPem_PKCS8(keyFilename);
}
else if(keyString.contains("BEGIN RSA PRIVATE KEY")){
return readPrivateKeyFromPem_PKCS1(keyFilename);
}
throw new Exception("Unknown private key format in "+keyFilename);
}我想在服务器端加密api,在android设备上解密数据,以避免未经授权的访问。
当在android上解密“输入字节数组在172处有不正确的结束字节”时,会抛出这个错误。
发布于 2021-06-04 01:08:15
在NodeJS代码中,密文是十六进制编码的,在Java码中是Base64解码的。这必须保持一致,无论是Base64编码还是十六进制编码。
此外,在Java代码中,在实例化密码时,只指定了算法。这导致默认填充被使用,例如在我的机器上(API28,Android9Pie)对应于RSA/ECB/NoPadding。这与使用PKCS#1 v1.5填充的RSA端不兼容(此外,没有填充的NodeJS,即所谓的教科书RSA端是不安全的)。因此,还必须在使用RSA/ECB/PKCS1Padding的密码实例化中指定填充。
使用PKCS#8格式的私钥和自己的readPrivateKeyFromPem_PKCS8()实现,如果上面提到的两个bug被修复,这两个代码都可以在我的机器上运行。但是,未发布的方法也可能包含缺陷。
https://stackoverflow.com/questions/67820367
复制相似问题