Ruby解密Java AES-GCM加密内容时遇OpenSSL::Cipher::CipherError问题
问题描述
对接第三方服务商时,对方采用AES/GCM/NoPadding加密方式,用Ruby解密时抛出OpenSSL::Cipher::CipherError错误。发现Java端使用16字节全零数组作为IV,但自己误以为Ruby仅支持12字节IV,不清楚问题根源。
对方Java加密代码:
SecretKey sessionKey = getSessionKey(); byte[] IV = new byte[16]; Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); SecretKeySpec keySpec = new SecretKeySpec(sessionKey.getEncoded(), "AES"); GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(16 * 8, IV); cipher.init(Cipher.ENCRYPT_MODE, keySpec, gcmParameterSpec); byte[] encryptedText = cipher.doFinal(plaintext); responseMap.put("data", Base64.getEncoder().encodeToString(encryptedText));
自己的Ruby解密代码:
decrypted_key = "AES KEY" decode_data = Base64.strict_decode64(params["data"]) cipher_text_with_auth_tag = decode_data.unpack("C*") auth_tag = cipher_text_with_auth_tag.last(16).pack("C*") cipher_text = cipher_text_with_auth_tag[0..-17].pack("c*") decipher = OpenSSL::Cipher.new('AES-256-GCM') decipher.decrypt decipher.padding = 0 decipher.key = decrypted_key decipher.iv = "\x00" * 12 decipher.auth_data = '' decipher.auth_tag = auth_tag decrypted_data = decipher.update(cipher_text) + decipher.final
问题分析与解决
核心问题:IV不匹配
GCM模式允许12字节(推荐)或其他长度(如16字节)的IV,Ruby的OpenSSL库完全支持16字节IV,你之前的误解是错误的。Java端用的是16字节全零IV,而Ruby代码里用了12字节,这是导致解密失败的直接原因。
其他潜在问题
- 密钥处理错误:代码中
decrypted_key是字符串形式,若服务商提供的密钥是Base64编码的,需要先解码为二进制数据,否则密钥长度或格式不符会导致解密失败。 - 认证标签拆分逻辑:Java的GCM加密默认不会自动将认证标签附加到密文后,若对方代码未手动拼接密文和标签,你当前拆分最后16字节作为标签的逻辑就是错误的,需确认对方的
data格式是否为「密文+16字节认证标签」。
修正后的Ruby解密代码
# 假设密钥是Base64编码,需先解码;若为原始二进制可跳过此步 decrypted_key = Base64.strict_decode64("服务商提供的AES密钥") decode_data = Base64.strict_decode64(params["data"]) # 拆分密文和认证标签(确认对方data是密文+16字节标签的格式) cipher_text = decode_data[0...-16] auth_tag = decode_data[-16..-1] decipher = OpenSSL::Cipher.new('AES-256-GCM') decipher.decrypt decipher.key = decrypted_key # 使用和Java一致的16字节全零IV decipher.iv = "\x00" * 16 decipher.auth_data = '' # 和加密端保持一致,若加密时有AAD需同步设置 decipher.auth_tag = auth_tag decrypted_data = decipher.update(cipher_text) + decipher.final
内容的提问来源于stack exchange,提问作者Catch Me HuntEr
相关产品推荐
相关产品推荐

