我在 Android 上生成 rsa public/private 使用:
KeyPairGenerator kpg;
KeyPair kp;
PublicKey publicKey;
PrivateKey privateKey;
kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(2048);
kp = kpg.genKeyPair();
publicKey = kp.getPublic();
privateKey = kp.getPrivate();
然后我将公钥发送到 Windows 并使用 OpenSSL 库加密数据:
int resEncryption = RSA_public_encrypt(length, in, encrypted, rsaPkey, RSA_PKCS1_OAEP_PADDING);
然后我在 Windows 上将加密转换为 HEX:
stringstream ss;
for (int i = 0; i < resEncryption; i++)
ss << std::hex << (int)encrypted[i] << std::setfill('0');
string hexEncrypted = ss.str();
我在 Android 上得到 hexEncrypted 并将其放入字符串中:
StringBuilder sb = new StringBuilder();
char[] hexData = hex.toCharArray();
for (int count = 0; count < hexData.length - 1; count += 2) {
int firstDigit = Character.digit(hexData[count], 16);
int lastDigit = Character.digit(hexData[count + 1], 16);
int decimal = firstDigit * 16 + lastDigit;
sb.append((char)decimal);
}
String hexDecrypted = sb.toString();
为了解密这些数据,我做了:
byte[] encryptedBytes = hexDecrypted.getBytes();
Cipher cipher1 = Cipher.getInstance("RSA/None/OAEPwithSHA-1andMGF1Padding");//also tried RSA/ECB/OAEPwithSHA-1andMGF1Padding
cipher1.init(Cipher.DECRYPT_MODE, privateKey);
decryptedBytes = cipher1.doFinal(encryptedBytes);
但我在 CipherSpi.class 的 engineDoFinal 方法中遇到错误:
protected byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen) throws IllegalBlockSizeException, BadPaddingException {
if(input != null) {
this.bOut.write(input, inputOffset, inputLen);
}
if(this.cipher instanceof RSABlindedEngine) {
if(this.bOut.size() > this.cipher.getInputBlockSize() + 1) {
throw new ArrayIndexOutOfBoundsException("too much data for RSA block");
}
} else if(this.bOut.size() > this.cipher.getInputBlockSize()) {
throw new ArrayIndexOutOfBoundsException("too much data for RSA block");//Error here
}
return this.getOutput();
}
最佳答案
看起来我在使用 C++ 进行十六进制转换时遇到了问题,这解决了我的问题。现在,我在 Android 上获得了预期长度的十六进制字符串。
string asciiResEnc(reinterpret_cast<char*>(encrypted), resEncryption);
stringstream ss;
for(int i = 0; i < asciiResEnc.size(); i++)
ss << std::hex << setw(2) << setfill('0') << (int) (unsigned char)asciiResEnc[i];
关于java - Windows上使用openssl C++的RSA加密/解密错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49191002/