Java BadPaddingException:数据必须以零开头-为什么?
我需要编写一个java代码,使用客户提供的私钥/公钥对消息进行加密/解密。 以下是我所做的:Java BadPaddingException:数据必须以零开头-为什么?,java,encryption,openssl,rsa,badpaddingexception,Java,Encryption,Openssl,Rsa,Badpaddingexception,我需要编写一个java代码,使用客户提供的私钥/公钥对消息进行加密/解密。 以下是我所做的: 我从客户那里得到了PKCS#1格式的私钥(它以------BEGIN RSA私钥------开头) 我使用以下命令将其转换为PKCS#8: openssl pkcs8 -topk8 -nocrypt -in private_pkcs1.key -out private_pkcs8.key openssl rsa -in private_pkcs8.key -pubout > public.ke
- 我从客户那里得到了PKCS#1格式的私钥(它以------BEGIN RSA私钥------开头)
- 我使用以下命令将其转换为PKCS#8:
openssl pkcs8 -topk8 -nocrypt -in private_pkcs1.key -out private_pkcs8.key
openssl rsa -in private_pkcs8.key -pubout > public.key
- 现在我有了PKCS#8格式的私钥(以------BEGIN private key------开头)
- 我已使用以下命令从私钥中提取出公钥(使用两种格式进行了尝试,得到了相同的公钥):
openssl pkcs8 -topk8 -nocrypt -in private_pkcs1.key -out private_pkcs8.key
openssl rsa -in private_pkcs8.key -pubout > public.key
- 我编写了以下方法来读取私钥private_pkcs8.key文件:
private static PrivateKey readPrivateKey(String filename) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException { File file = new File(filename); FileInputStream in = new FileInputStream(file); byte[] keyBytes = new byte[ new Long(file.length()).intValue() ]; in.read(keyBytes); in.close(); String strPrivateKey = new String(keyBytes, "UTF-8").replaceAll("(-+BEGIN PRIVATE KEY-+\\r?\\n|-+END PRIVATE KEY-+\\r?\\n?)", ""); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(DatatypeConverter.parseBase64Binary(strPrivateKey)); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); return keyFactory.generatePrivate(keySpec); }
- 我编写了以下方法从public.key文件中读取公钥
private static PublicKey readPublicKey(String filename) throws NoSuchAlgorithmException, InvalidKeySpecException, IOException { File file = new File(filename); FileInputStream in = new FileInputStream(file); byte[] keyBytes = new byte[ new Long(file.length()).intValue() ]; in.read(keyBytes); in.close(); String strPublicKey = new String(keyBytes, "UTF-8").replaceAll("(-+BEGIN PUBLIC KEY-+\\r?\\n|-+END PUBLIC KEY-+\\r?\\n?)", ""); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(DatatypeConverter.parseBase64Binary(strPublicKey)); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); return keyFactory.generatePublic(keySpec); }
- 我编写了以下加密方法
private static byte[] encrypt(byte[] message, Key key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchProviderException, InvalidAlgorithmParameterException { Cipher cipher = Cipher.getInstance(ALGORITHEM); cipher.init(Cipher.ENCRYPT_MODE, key); return cipher.doFinal(message); }
private static byte[] decrypt(byte[] message, Key key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchProviderException, InvalidAlgorithmParameterException { Cipher cipher = Cipher.getInstance(ALGORITHEM); cipher.init(Cipher.DECRYPT_MODE, key); return cipher.doFinal(message); }
- 我编写了以下解密方法
private static byte[] encrypt(byte[] message, Key key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchProviderException, InvalidAlgorithmParameterException { Cipher cipher = Cipher.getInstance(ALGORITHEM); cipher.init(Cipher.ENCRYPT_MODE, key); return cipher.doFinal(message); }
private static byte[] decrypt(byte[] message, Key key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchProviderException, InvalidAlgorithmParameterException { Cipher cipher = Cipher.getInstance(ALGORITHEM); cipher.init(Cipher.DECRYPT_MODE, key); return cipher.doFinal(message); }
- 我已经编写了以下主要的测试应用程序,它试图加密一个简单的字符串并将其解密回来
public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException, IOException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, SignatureException, NoSuchProviderException, InvalidAlgorithmParameterException { readKeys(); String messageToEncrypt = "This is the string I want to test"; log("Original Message: " + messageToEncrypt); byte[] originalBytes = messageToEncrypt.getBytes("UTF-8"); byte[] encriptedBytes = encrypt(originalBytes, privateKey); byte[] decriptedMessage = decrypt(encriptedBytes, publicKey); log("Decripted Message: " + new String(decriptedMessage)); }
- 加密还可以,但当我尝试将其解密回原始消息时,我遇到了以下异常:
Exception in thread "main" javax.crypto.BadPaddingException: Data must start with zero at sun.security.rsa.RSAPadding.unpadV15(Unknown Source) at sun.security.rsa.RSAPadding.unpad(Unknown Source) at com.sun.crypto.provider.RSACipher.a(DashoA13*..) at com.sun.crypto.provider.RSACipher.engineDoFinal(DashoA13*..) at javax.crypto.Cipher.doFinal(DashoA13*..) at com.company.encryption.utils.RsaUtils.decrypt(RsaUtils.java:95) at com.company.encryption.utils.RsaUtils.main(RsaUtils.java:108) ERROR: JDWP Unable to get JNI 1.2 environment, jvm->GetEnv() return code = -2 JDWP exit error AGENT_ERROR_NO_JNI_ENV(183): [../../../src/share/back/util.c:820]
- 当我替换了私钥/公钥并使用KeyPairGenerator时,一切正常。这让我得出结论,密钥、读取密钥的方式或用于加密/解密的算法有问题。(我试过使用“RSA”、“RSA/ECB/PKCS1P”-但没有成功)
Guy Hudara在非对称密码中,使用公钥加密,使用私钥解密。通过这种方式,它确保任何人都可以使用众所周知的公钥对消息进行加密,但只有私钥持有者可以对其进行解密
byte[] encryptedBytes = encrypt(originalBytes, publicKey);
byte[] decryptedBytes = decrypt(encryptedBytes, privateKey);
我也有同样的问题。通过重新生成公钥解决。一般来说,您是正确的。但在我的情况下,我不在乎“任何人”都能加密信息。我想让我的客户确认这封信是我发的,而且是我发的。我最初的问题是什么?为什么我会得到这个例外?你知道吗?如果你想要认证,你应该使用签名而不是加密。签名由私钥生成,并由公钥验证。对于您最初的问题-Sun security provider可能不支持使用公钥进行解密,因此出现了错误。我尝试使用公钥进行加密-正如您所建议的那样-并在加密方法中得到了相同的异常(BadPaddingException)。此外,如果我不尝试从文件加载密钥,但我生成自己的密钥对(使用KeyPairGenerator),那么一切都可以正常工作,包括使用公钥解密。这让我觉得我的公钥有问题。可能我使用的算法/模式/填充与密钥不匹配?我如何验证这一点?我假设openssl和KeyFactory.generatePublic()受到投诉,如果这是一个密钥损坏问题的话。没有人投诉):