为什么我无法在Java环境中解码来自安卓设备的字符串?

huangapple go评论96阅读模式
英文:

Why i can not decode the string coming from Android devices with Java environment?

问题

我使用 Android 设备使用以下代码对字符串进行加密:

在 Android 端,密钥长度:2048

  1. //初始化:需要一些时间
  2. private void prepareEncrypt(String publicKey) throws Exception {
  3. X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKey.getBytes()));
  4. KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  5. PublicKey pubKey = keyFactory.generatePublic(keySpec);
  6. cp = Cipher.getInstance("RSA/ECB/OAEPWithSHA-512AndMGF1Padding");
  7. cp.init(Cipher.ENCRYPT_MODE, pubKey);
  8. }
  9. //加密
  10. private byte[] encryptByPublicKey(byte[] data) {
  11. byte[] result = new byte[0];
  12. try {
  13. result = cp.doFinal(data);
  14. } catch (BadPaddingException e) {
  15. e.printStackTrace();
  16. } catch (IllegalBlockSizeException e) {
  17. e.printStackTrace();
  18. }
  19. return result;
  20. }

得到密文 A。

然后,我尝试在 Eclipse 上使用 Java 解码 A:

  1. public static byte[] decryptByPrivateKey(byte[] encrypted, byte[] privateKey) throws Exception {
  2. PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey));
  3. KeyFactory kf = KeyFactory.getInstance("RSA");
  4. PrivateKey keyPrivate = kf.generatePrivate(keySpec);
  5. Cipher cp = Cipher.getInstance("RSA/ECB/OAEPWithSHA-512AndMGF1Padding");
  6. cp.init(Cipher.DECRYPT_MODE, keyPrivate);
  7. byte[] arr = cp.doFinal(Base64.getDecoder().decode(encrypted));
  8. return arr;
  9. }

我总是无法成功解码字符串。

  1. javax.crypto.BadPaddingException: Decryption error
  2. at sun.security.rsa.RSAPadding.unpadOAEP(Unknown Source)
  3. at sun.security.rsa.RSAPadding.unpad(Unknown Source)
  4. at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:363)
  5. at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:389)

如果 Android 端不更改 Cipher 对象上的 TRANSFORMATION 参数,例如:

RSA/ECB/NoPadding

RSA/ECB/PKCS1Padding

RSA/ECB/OAEPWithSHA-1AndMGF1Padding

RSA/ECB/OAEPWithSHA-224AndMGF1Padding

RSA/ECB/OAEPWithSHA-256AndMGF1Padding

RSA/ECB/OAEPWithSHA-384AndMGF1Padding

RSA/ECB/OAEPWithSHA-512AndMGF1Padding

如何成功解码密文 A?

英文:

I use Android deivces to encript a string with these code:

Android side , key length : 2048

  1. //Init: need time
  2. private void prepareEncrypt(String publicKey) throws Exception {
  3. X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKey.getBytes()));
  4. KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  5. PublicKey pubKey = keyFactory.generatePublic(keySpec);
  6. cp = Cipher.getInstance("RSA/ECB/OAEPWithSHA-512AndMGF1Padding");
  7. cp.init(Cipher.ENCRYPT_MODE, pubKey);
  8. }
  9. //encrypt
  10. private byte[] encryptByPublicKey(byte[] data) {
  11. //data = Base64.getEncoder().encode(data);
  12. byte[] result = new byte[0];
  13. try {
  14. result = cp.doFinal(data);
  15. } catch (BadPaddingException e) {
  16. e.printStackTrace();
  17. } catch (IllegalBlockSizeException e) {
  18. e.printStackTrace();
  19. }
  20. return result;
  21. }

Get a Ciphertext A.

Then i tried to decode the A with Java on elipse:

  1. public static byte[] decryptByPrivateKey(byte[] encrypted, byte[] privateKey) throws Exception {
  2. PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey));
  3. KeyFactory kf = KeyFactory.getInstance("RSA");
  4. PrivateKey keyPrivate = kf.generatePrivate(keySpec);
  5. Cipher cp = Cipher.getInstance("RSA/ECB/OAEPWithSHA-512AndMGF1Padding");
  6. cp.init(Cipher.DECRYPT_MODE, keyPrivate);
  7. byte[] arr = cp.doFinal(Base64.getDecoder().decode(encrypted));
  8. return arr;
  9. }

I always failed to decode the String.

  1. javax.crypto.BadPaddingException: Decryption error
  2. at sun.security.rsa.RSAPadding.unpadOAEP(Unknown Source)
  3. at sun.security.rsa.RSAPadding.unpad(Unknown Source)
  4. at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:363)
  5. at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:389)

If the Android do not change the TRANSFORMATION paremeter on object Cipher Like:

RSA/ECB/NoPadding

RSA/ECB/PKCS1Padding

RSA/ECB/OAEPWithSHA-1AndMGF1Padding

RSA/ECB/OAEPWithSHA-224AndMGF1Padding

RSA/ECB/OAEPWithSHA-256AndMGF1Padding

RSA/ECB/OAEPWithSHA-384AndMGF1Padding

RSA/ECB/OAEPWithSHA-512AndMGF1Padding

How to decode the Ciphertext A successfully?

答案1

得分: 1

OAEPParameterSpec oaepParameterSpecDec = new OAEPParameterSpec("SHA-512", "MGF1", new MGF1ParameterSpec("SHA-512"), PSource.PSpecified.DEFAULT);
...
cp.init(Cipher.DECRYPT_MODE, keyPrivate, oaepParameterSpecDec);

显然提供了填充参数。

英文:

Need this :

  1. OAEPParameterSpec oaepParameterSpecDec = new OAEPParameterSpec("SHA-512", "MGF1", new MGF1ParameterSpec("SHA-512"), PSource.PSpecified.DEFAULT);
  2. ...
  3. cp.init(Cipher.DECRYPT_MODE, keyPrivate, oaepParameterSpecDec);

obviously give the padding paremeters

huangapple
  • 本文由 发表于 2020年9月4日 11:46:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/63734564.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定