Ruby Cipher解密Java加密的内容时出现错误。

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

Ruby Cipher Error on decrypting something encrypted with Java

问题

在Ruby中尝试解密时遇到错误 OpenSSL::Cipher::CipherError ()。 我观察到在Java中,IV接受了16个字节(全是零的数组),而Ruby仅限于12个字节。 我在这里遗漏了一些东西。 非常感谢您提前的帮助。

Java代码片段

  1. SecretKey sessionKey = getSessionKey();
  2. byte[] IV = new byte[16];
  3. Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
  4. SecretKeySpec keySpec = new SecretKeySpec(sessionKey.getEncoded(), "AES");
  5. GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(16 * 8, IV);
  6. cipher.init(Cipher.ENCRYPT_MODE, keySpec, gcmParameterSpec);
  7. byte[] encryptedText = cipher.doFinal(plaintext);
  8. responseMap.put("data", Base64.getEncoder().encodeToString(encryptedText));

Ruby代码片段

  1. decrypted_key = "AES KEY"
  2. decode_data = Base64.strict_decode64(params["data"])
  3. cipher_text_with_auth_tag = decode_data.unpack("C*")
  4. auth_tag = cipher_text_with_auth_tag.last(16).pack("C*")
  5. cipher_text = cipher_text_with_auth_tag[0..-17].pack("c*")
  6. decipher = OpenSSL::Cipher.new('AES-256-GCM')
  7. decipher.decrypt
  8. decipher.padding = 0
  9. decipher.key = decrypted_key
  10. decipher.iv = "\x00" * 12
  11. decipher.auth_data = ''
  12. decipher.auth_tag = auth_tag
  13. decrypted_data = decipher.update(cipher_text) + decipher.final
英文:

I have received the encryption request from a different provider, they were using AES GCM No Padding. When I am trying to decrypt it in ruby getting an error OpenSSL::Cipher::CipherError (). I observed in Java the IV is accepting the 16 bytes(Array of Zeros) whereas ruby is limited to 12 bytes only. I am missing something here. Appreciate your help in advance

Code Snippet for Java

  1. SecretKey sessionKey = getSessionKey();
  2. byte[] IV = new byte[16];
  3. Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
  4. SecretKeySpec keySpec = new SecretKeySpec(sessionKey.getEncoded(), "AES");
  5. GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(16 * 8, IV);
  6. cipher.init(Cipher.ENCRYPT_MODE, keySpec, gcmParameterSpec);
  7. byte[] encryptedText = cipher.doFinal(plaintext);
  8. responseMap.put("data", Base64.getEncoder().encodeToString(encryptedText));

Code snippet for Ruby

  1. decrypted_key = "AES KEY"
  2. decode_data = Base64.strict_decode64(params["data"])
  3. cipher_text_with_auth_tag = decode_data.unpack("C*")
  4. auth_tag = cipher_text_with_auth_tag.last(16).pack("C*")
  5. cipher_text = cipher_text_with_auth_tag[0..-17].pack("c*")
  6. decipher = OpenSSL::Cipher.new('AES-256-GCM')
  7. decipher. decrypt
  8. decipher.padding = 0
  9. decipher.key = decrypted_key
  10. decipher.iv = "\x00" * 12
  11. decipher.auth_data = ''
  12. decipher.auth_tag = auth_tag
  13. decrypted_data = decipher.update(cipher_text) + decipher.final

答案1

得分: 2

你可以在 OpenSSL 中使用不同的 IV/nonce 长度,但你需要先调用 iv_len=

类似这样应该可以工作:

  1. decipher = OpenSSL::Cipher.new('AES-256-GCM')
  2. decipher.decrypt
  3. decipher.key = key
  4. # 在设置 iv= 之前调用 iv_len=
  5. decipher.iv_len = iv_len # 例如,在你的情况下是 16
  6. decipher.iv = iv
  7. decipher.auth_data = ''
  8. decipher.auth_tag = auth_tag
  9. decrypted_data = decipher.update(encrypted_data) + decipher.final()
英文:

You can use a different IV/nonce length in OpenSSL, but you need to call iv_len= first.

something like this should work:

  1. decipher = OpenSSL::Cipher.new('AES-256-GCM')
  2. decipher.decrypt
  3. decipher.key = key
  4. # Call iv_len= before iv=
  5. decipher.iv_len = iv_len # e.g. 16 in your case
  6. decipher.iv = iv
  7. decipher.auth_data = ''
  8. decipher.auth_tag = auth_tag
  9. decrypted_data = decipher.update(encrypted_data) + decipher.final()

huangapple
  • 本文由 发表于 2023年6月16日 03:31:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/76484980.html
匿名

发表评论

匿名网友

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

确定