在c#和PHP中使用AES中的Salt
本文关键字:AES 中的 Salt PHP | 更新日期: 2023-09-27 17:51:03
我正在尝试使用AES编码和解码字符串。目前,我在Mono c#中使用最高评级的答案编码字符串,因为System.Security.Crytpography.Aes
在Mono中不可用。然而,这个实现使用了一个Salt,而我用来解密它的PHP方法不使用Salt,只使用我生成的Initialization Vector。
我的问题:加密的数据是加盐的,我不知道如何用已知的盐字符串解除盐。
- 我应该试着从c#类中移除盐吗?
- 仅使用明文,密码/密钥和初始化向量的实现是否足够好?
或者有另一种形式的解密,我可以在PHP中使用,将采取密文,密钥,盐和初始化矢量? - 或者我应该在调用
mcrypt_decrypt
后尝试解除解密文本的盐?这是正确的顺序吗? 或者我应该完全重写c# AES类吗?这真的是一个坏例子吗?或者有人知道我可以在PHP中使用的
Rfc2898DeriveBytes
实现吗?我不确定我是否有足够的信心自己编写实现,以免我通过一些错误完全击败安全点。很抱歉我的无知,这是我第一次处理加密,而且有很多信息要吸收。
您发布的答案实现了Rfc2898DeriveBytes
类来获取加密密钥的字节。建议这样做,但不是强制性的。您不必使用Rfc2898DeriveBytes
,并且可以简单地修改AES实现,使其不使用salt,而是直接将密码的字节作为密钥。虽然我不建议在实践中这样做。
我建议的是找到一个更合适的PHP AES实现,允许您的密码盐渍以获得密钥字节-这应该是可用的(对不起,但我几乎没有PHP经验来帮助您;您可能会发现PHP加密库中存在一个额外的方法,可以根据密码和盐输入(类似于. net/mono的Rfc2898DeriveBytes
)来生成密钥。
#1 No
#2是(见下文)
# 3没有
不,我觉得挺好的。#5请尝试使用这个PHP实现加密数据。我还没有测试过。
<?php
function pbkdf2( $p, $s, $c, $kl, $a = 'sha1' ) {
$hl = strlen(hash($a, null, true)); # Hash length
$kb = ceil($kl / $hl); # Key blocks to compute
$dk = ''; # Derived key
# Create key
for ( $block = 1; $block <= $kb; $block ++ ) {
# Initial hash for this block
$ib = $b = hash_hmac($a, $s . pack('N', $block), $p, true);
# Perform block iterations
for ( $i = 1; $i < $c; $i ++ )
# XOR each iterate
$ib ^= ($b = hash_hmac($a, $b, $p, true));
$dk .= $ib; # Append iterated block
}
# Return derived key of correct length
return substr($dk, 0, $kl);
}
//Usage example (Decryption by PHP)
$ciphertext_b64 = "owiCMbopBmr+NvjBEUT2Hg==";
$password = "password";
$salt = "g46dzQ80"; //Please change to the salt you are using. Copied from the referenced answer code.
//This is the key derivation part. I think .net uses 1000 iterations of sha1.
$key = pbkdf2($password, $salt, 1000, 32, "sha1");
$iv = "OFRna74m*aze01xY"; //Again, I copied the IV from the .NET code in the answer you referenced.
$plaintext = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, base64_decode($ciphertext_b64), MCRYPT_MODE_CBC, $iv), "'0");
echo $plaintext;
// Output = hello