我想在PHP,Ruby(使用SymmetricEncryption)和Javascript(使用CryptoJS)中进行AES-256 CBC加密。作为第一2:如何生成可以共享为字符串的AES-256 CBC密钥/ iv?
<?php
openssl_encrypt(
'Hello!', 'aes-256-cbc',
'1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF',
0,
'1234567890ABCDEF1234567890ABCDEF'
); // => 'BAd5fmmMTvRE4Ohvf3GpCw=='
ruby_cipher = SymmetricEncryption::Cipher.new(
key: "1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF",
iv: "1234567890ABCDEF1234567890ABCDEF",
cipher_name: 'aes-256-cbc'
)
ruby_cipher.encrypt("Hello!") # => 'BAd5fmmMTvRE4Ohvf3GpCw=='
但根据this answer上述键/仅iv提供128位的安全性。
PHP和Ruby将密钥和IV作为二进制字符串。他们不认为它是十六进制编码的。所以,虽然这个密钥有256位,但安全性实际上只有128位,因为每个字符在Hex编码的字符串中只有4位。
因此,只使用一半的密钥/ iv在CryptoJS中提供相同的加密结果。
CryptoJS.AES.encrypt(
"Hello!",
CryptoJS.enc.Utf8.parse('1234567890ABCDEF1234567890ABCDEF'),
iv: CryptoJS.enc.Utf8.parse('1234567890ABCDEF')
).toString() // 'BAd5fmmMTvRE4Ohvf3GpCw=='
如何生成字符串键和提供256位安全性的iv?
请勿将字符串用作关键字。使用32字节长度的随机生成密钥。然后你得到所有256位的随机性。 –
如果密钥大于32个字节,任何好的API都会引发异常。因为该方法只接收到一个指向内存位置的指针,所以C可以稍微宽恕一些。 Ruby的唯一借口是它依赖于本地库 - 但这并不意味着它无法检查输入的大小。任何良好的语言都可以区分字符串和二进制。这种代码是一个等待发生的错误(如果它还没有发生)。 –