RC2实现的差异C#和Python?

问题描述 投票:-1回答:1

出于兼容性/传统原因,我需要使用RC2加密在CBC模式下。我正在编写测试-但在C#,Python和在线工具中,(似乎)输入值相同,结果却截然不同。

对于所有实现,我都使用以下数据:

Data: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 
Key: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00    
IV: 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08   
Mode: CBC    
Padding: PKCS7

我曾尝试使用Python,C#和一个名为Cyber​​Chef的在线工具对此进行测试。所有人给我的结果完全不同。

Python结果d123f2ac56146f3cebd19b285eb1e1744b828a177778be07

C#结果f278304ee422a8bbccd54c9157afa818ac4e5b21858ff267

Cyber​​Chef结果c91e276fc97e71acb72426f29c3a6c6f5181d8e83dcf1a98

Python脚本:

from Crypto.Cipher import ARC2
from Crypto.Util.Padding import pad
input = bytes([0]*16)
key = bytes([0]*8)
iv = b"\x01\x02\x03\x04\x05\x06\x07\x08"

cipher = ARC2.new(key, ARC2.MODE_CBC, iv=iv)

msg = cipher.encrypt(pad(input,8,style='pkcs7'))
print("{} {}".format(len(msg), msg.hex()))

C#脚本(部分):

public byte[] Encrypt(Rc2CryptoParameters cryptoParameters)
{
    using var outputStream = new MemoryStream();
    using var provider = GetRc2Provider(cryptoParameters);
    using var encryptor = provider.CreateEncryptor();
    using var cryptoStream = new CryptoStream(outputStream, encryptor, CryptoStreamMode.Write);

    cryptoStream.Write(cryptoParameters.Data);
    cryptoStream.Close();
    return outputStream.ToArray();
}

private RC2CryptoServiceProvider GetRc2Provider(Rc2CryptoParameters cryptoParameters)
{
    return new RC2CryptoServiceProvider
    {
        Key = cryptoParameters.Key,
        BlockSize = cryptoParameters.BlockSize,
        KeySize = cryptoParameters.KeySize,
        Padding = cryptoParameters.PaddingMode,
        Mode = cryptoParameters.CipherMode
    };
}

public Rc2CryptoParameters(byte[] data, byte[] key, byte[] iv)
{
    Data = data;
    Iv = iv;
    Key = key;
    CipherMode = CipherMode.CBC;
    PaddingMode = PaddingMode.PKCS7;
}

所以-为什么我到处都得到不同的结果?我尝试使用一些CBC测试向量,我只能找到的是这些:http://cryptomanager.com/tv.html

如何确定哪个结果正确?为什么所有的实现都产生不同的结果?

c# encryption cryptography encryption-symmetric arc2
1个回答
0
投票

RC2在RFC2268中描述。这是具有可变密钥长度的分组密码,并且具有一个称为有效密钥长度(以位为单位)>>的附加参数,请参见RFC2268, Section 2。在这两个代码中以及在网站上,使用了不同的有效密钥长度(以位为单位),从而导致不同的结果。

在Python代码中,当使用PyCryptodome时,在创建effective_keylen -cipher实例时,使用参数ARC2指定有效密钥长度(以位为单位),该实例的值可能在40到1024之间,其中默认值为1024值。由于未在发布的Python代码中明确指定该参数,因此将使用默认值。请注意,此参数在PyCrypto文档中有所描述,但在PyCryptodome文档中没有描述。

website的密文将得出effective_keylen = 128。在网站上似乎无法更改有效密钥长度(以位为单位)。

无法复制C#代码的密文,可能是因为GetRc2Provider中未设置IV(因此使用了随机生成的IV)。如果这是固定的,则可以看出以位(RC2CryptoServiceProvider#EffectiveKeySize)为单位的有效密钥长度被隐式设置为实际密钥长度。如果将参数显式切换为另一个值,则会抛出System.Security.Cryptography.CryptographicUnexpectedOperationException: EffectiveKeySize must be the same as KeySize in this implementation.

© www.soinside.com 2019 - 2024. All rights reserved.