在C#和PHP中使用AES中的盐

在C#和PHP中使用AES中的盐,c#,php,encryption,mono,aes,C#,Php,Encryption,Mono,Aes,我正在尝试使用AES对字符串进行编码和解码。目前,我正在使用评分最高的答案用Mono C#对字符串进行编码,因为Mono中没有System.Security.crytphography.Aes。然而,这个实现使用了一个Salt,我用来解密它的不是Salt,而是我生成的初始化向量 我的问题:加密的数据是腌制的,即使使用已知的盐字符串,我也不知道如何将其解盐 我应该试着把C#class上的盐去掉吗? 仅使用明文、密码/密钥和初始化向量的实现是否足够好 或者我可以在PHP中使用另一种形式的解密,它

我正在尝试使用AES对字符串进行编码和解码。目前,我正在使用评分最高的答案用Mono C#对字符串进行编码,因为Mono中没有
System.Security.crytphography.Aes
。然而,这个实现使用了一个Salt,我用来解密它的不是Salt,而是我生成的初始化向量

我的问题:加密的数据是腌制的,即使使用已知的盐字符串,我也不知道如何将其解盐

  • 我应该试着把C#class上的盐去掉吗?
    • 仅使用明文、密码/密钥和初始化向量的实现是否足够好
  • 或者我可以在PHP中使用另一种形式的解密,它将采用密文、密钥、salt和初始化向量
  • 或者我应该在调用
    mcrypt\u decrypt
    后尝试对解密文本进行解盐吗?这是事情的正确顺序吗
  • 还是我应该完全重写C#AES类?这真的是一个坏例子吗
  • [编辑]或者有人知道我可以在PHP中使用的
    Rfc2898DeriveBytes
    实现吗?我不确定自己是否有足够的信心自己编写实现,以免由于某些错误而完全破坏安全性
  • 很抱歉我的无知,这是我第一次处理加密,有很多信息需要接受。

    答案实现了
    Rfc2898DeriveBytes
    类来获取加密密钥的字节。您不必使用
    Rfc2898DeriveBytes
    ,只需修改AES实现即可,不必使用salt,只需直接使用密码字节作为密钥。虽然我不建议在实践中这样做

    我推荐的是找到一个更合适的PHP AES实现,它允许对密码进行盐析以获取密钥字节,而密钥字节应该是可用的(很抱歉,我在PHP方面没有什么经验可以帮助您做到这一点;您可能会发现PHP加密库中还存在一种基于密码和salt输入形成密钥的方法,类似于.NET/MONO的
    Rfc2898DeriveBytes

    我推荐的是找到一个更合适的PHP AES实现,它允许对密码进行盐析以获取密钥字节,而密钥字节应该是可用的(很抱歉,我在PHP方面没有什么经验可以帮助您做到这一点;您可能会发现PHP加密库中还存在一种基于密码和salt输入形成密钥的方法,类似于.NET/MONO的
    Rfc2898DeriveBytes

    我推荐的是找到一个更合适的PHP AES实现,它允许对密码进行盐析以获取密钥字节,而密钥字节应该是可用的(很抱歉,我在PHP方面没有什么经验可以帮助您做到这一点;您可能会发现PHP加密库中还存在一种基于密码和salt输入形成密钥的方法,类似于.NET/MONO的
    Rfc2898DeriveBytes

    我推荐的是找到一个更合适的PHP AES实现,它允许对密码进行盐析以获取密钥字节,而密钥字节应该是可用的(很抱歉,我对PHP没有什么经验可以帮助您做到这一点;您可能会发现PHP加密库中还存在一种基于密码和salt输入的方法,类似于.NET/MONO的
    Rfc2898DeriveBytes
    )。

    1否

    #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
    
    #1个

    #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
    
    #1个

    #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
    
    #1个

    #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
    

    不可能取消某些内容的salt。您必须在PHP中重新创建相同的密钥派生代码。提示:可能是PBKDF2。您必须问问自己,您需要的是基于密码的解决方案还是基于密钥的解决方案。因此,在仔细阅读该代码后,我需要做的是从源代码派生一组新的字节,用作解密密钥最后的密码/密钥和salt?我有这个权利吗?这意味着我仍然需要在PHP中实现
    Rfc2898DeriveBytes
    ,正如@oscho的回答中所述,我想?不可能取消某些内容的salt。您必须在PHP中重新创建相同的密钥派生代码。提示:可能是PBKDF2。您必须问问自己是否需要pas基于剑的解决方案或基于键的解决方案。所以在仔细阅读代码之后,我要做的是派生一组新的字节用作de