Bad Padding Exception - RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING in pkcs11

霸气de小男生 提交于 2019-11-29 02:45:11

You obtain a non-extractable private key P11Key.P11PrivateKey from the dongle. It cannot be used outside PKCS11 provider, thus, SunPKCS11 provider should be used for operations with that key.

Unfortunately SunPKCS11 provider doesn't support OAEP padding, making it more difficult. Encryption still can be done with BouncyCastle, but decryption can be done with no padding and SunPKCS11 provider. keyLength parameter is RSA key modulus length in bits (1024,2048 etc).

private void testEncryption(byte[] plainText, PrivateKey privateKey, PublicKey publicKey, int keyLength) throws GeneralSecurityException {

    System.out.println("Plain text: " + DatatypeConverter.printHexBinary(plainText));

    Provider bcProvider = new BouncyCastleProvider();
    Cipher rsaCipher = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING", bcProvider);
    rsaCipher.init(Cipher.ENCRYPT_MODE, publicKey);
    byte[] cipherText = rsaCipher.doFinal(plainText);

    System.out.println("Cipher text: " + DatatypeConverter.printHexBinary(cipherText));

    Provider pkcs11provider = new SunPKCS11("C:\\Users\\manishs525\\pkcs11.cfg");
    Cipher rsaCipher2 = Cipher.getInstance("RSA/ECB/NoPadding", pkcs11provider);
    rsaCipher2.init(Cipher.DECRYPT_MODE, privateKey);
    byte[] paddedPlainText = rsaCipher2.doFinal(cipherText);

    /* Ensure leading zeros not stripped */
    if (paddedPlainText.length < keyLength / 8) {
        byte[] tmp = new byte[keyLength / 8];
        System.arraycopy(paddedPlainText, 0, tmp, tmp.length - paddedPlainText.length, paddedPlainText.length);
        System.out.println("Zero padding to " + (keyLength / 8));
        paddedPlainText = tmp;
    }           

    System.out.println("OAEP padded plain text: " + DatatypeConverter.printHexBinary(paddedPlainText));

    OAEPParameterSpec paramSpec = new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA1,
            PSource.PSpecified.DEFAULT);
    RSAPadding padding = RSAPadding.getInstance(RSAPadding.PAD_OAEP_MGF1, keyLength / 8, new SecureRandom(), paramSpec);
    byte[] plainText2 = padding.unpad(paddedPlainText);

    System.out.println("Unpadded plain text: " + DatatypeConverter.printHexBinary(plainText2));
}

Notes:

  • RSA/ECB/NoPadding is not implemented for SunPKCS11 before JDK1.7.
  • This example was tested with BouncyCastle 1.50 and JDK 1.7

I have found the issue is that the implementation of SunJCE's Cipher "RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING" is not compatible with other implementations (BouncyCastle/IAIK/PKCS11)

When setting AlgorithmParameters (with OAEPParameterSpec) an exception is thrown (javax.crypto.BadPaddingException)

Refer : Problems with Cipher "RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING" Bug Details

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!