java - Windows上使用openssl C++的RSA加密/解密错误

标签 java android encryption rsa

我在 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/

相关文章:

java - 创建公钥和私钥

java - 为什么 checkstyle 会提示这个?

java - 如何为基于gradle的Google App Engine项目在IntelliJ中启用带有断点的调试?

java - Selenium,验证字段格式是否正确

android - 错误 : app:transformClassesWithDexBuilderForDebug

security - 生成一个我可以证明我生成的 token

java - 使用 hibernate/jdbc 以值/对象列表作为参数从 java 代码调用存储过程

android - 如何生成用于模拟的 android.jar?

java - 借助Android上的SDK,如何改变iBeacon的参数值(UUID、Major、Minor、TxPower)

php - 使用 Javascript 来确认用 PHP 生成的哈希?