在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。

我的问题:加密的数据是加盐的,我不知道如何用已知的盐字符串解除盐。

  1. 我应该试着从c#类中移除盐吗?
    • 仅使用明文,密码/密钥和初始化向量的实现是否足够好?
  2. 或者有另一种形式的解密,我可以在PHP中使用,将采取密文,密钥,盐和初始化矢量?
  3. 或者我应该在调用mcrypt_decrypt后尝试解除解密文本的盐?这是正确的顺序吗?
  4. 或者我应该完全重写c# AES类吗?这真的是一个坏例子吗?或者有人知道我可以在PHP中使用的Rfc2898DeriveBytes实现吗?我不确定我是否有足够的信心自己编写实现,以免我通过一些错误完全击败安全点。

很抱歉我的无知,这是我第一次处理加密,而且有很多信息要吸收。

在c#和PHP中使用AES中的Salt

您发布的答案实现了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