用于加密的 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处有不正确的结束字节”,但会抛出这个错误。
在 NodeJS 代码中,密文采用十六进制编码,在 Java 代码中采用 Base64 解码。这必须是一致的,两边都是 Base64 或十六进制编码。
此外,在 Java 代码中,当实例化密码时,只指定了算法。这导致使用默认填充,例如在我的机器(API 28,Android 9 Pie)上对应于RSA/ECB/NoPadding
. 这与 NodeJS 端不兼容,它使用 PKCS#1 v1.5 填充(除了没有填充的 RSA,所谓的教科书 RSA,是不安全的)。因此,还必须在密码实例化中使用 指定填充RSA/ECB/PKCS1Padding
。
readPrivateKeyFromPem_PKCS8()
如果上述两个错误得到修复,则使用 PKCS#8 格式的私钥和两个代码的自己实现都可以在我的机器上运行。但是,未发布的方法也可能包含缺陷。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句