本文介绍了C#AES-256加密的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用RijndaelManaged做一个简单的加密/解密实用程序。这是正常工作,但我试图将其与在Unix(Oracle)中创建的另一个程序集成。我的问题是,对于所有较小的输入字符串,我得到与Unix代码一样的完全相同的加密十六进制,但对于较长的字符串,我加密十六进制的一半是相同的,但另一半是不同的:



Unix输出:

  012345678901234  -  00984BBED076541E051A239C02D97117 
0123456789012345678 - A0ACE158AD8CF70CEAE8F76AA27F62A30EA409ECE2F7FF84F1A9AF50817FC0C4

Windows输出(我的代码):

  012345678901234  -  00984BBED076541E051A239C02D97117(同上)
0123456789012345678 - A0ACE158AD8CF70CEAE8F76AA27F62A3D9A1B396A614DA2C1281AA1F48BC3EBB(与上述完全相同)

我的Windows代码是:

  public string Encrypt(byte [] PlainTextBytes,byte [] KeyBytes ,String InitialVector)
{
byte [] InitialVectorBytes = Encoding.ASCII.GetBytes(InitialVector);
RijndaelManaged SymmetricKey = new RijndaelManaged();
SymmetricKey.Mode = CipherMode.ECB;
SymmetricKey.Padding = PaddingMode.PKCS7;
ICryptoTransform Encryptor = SymmetricKey.CreateEncryptor(KeyBytes,InitialVectorBytes);
MemoryStream MemStream = new MemoryStream();
CryptoStream CryptoStream = new CryptoStream(MemStream,Encryptor,CryptoStreamMode.Write);
CryptoStream.Write(PlainTextBytes,0,PlainTextBytes.Length);
CryptoStream.FlushFinalBlock();
byte [] CipherTextBytes = MemStream.ToArray();
MemStream.Close();
CryptoStream.Close();
返回ByteToHexConversion(CipherTextBytes);
}

Unix(PL / SQL)代码:

  FUNCTION Encrypt_Card(plain_card_id VARCHAR2)
返回RAW AS
num_key_bytes NUMBER:= 256/8; - 密钥长度256位(32字节)
encrypted_raw RAW(2000); - 存储加密的二进制文本
encryption_type PLS_INTEGER:= - 总加密类型
DBMS_CRYPTO.ENCRYPT_AES256
+ DBMS_CRYPTO.CHAIN_CBC
+ DBMS_CRYPTO.PAD_PKCS5;

key_bytes_raw RAW(64):= my_hex_key;
BEGIN



encrypted_raw:= DBMS_CRYPTO.ENCRYPT

src => UTL_I18N.STRING_TO_RAW(plain_card_id,'AL32UTF8') ,
typ => encryption_type,
key => key_bytes_raw
);


返回encrypted_raw;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line(plain_card_id ||' - '|| SUBSTR(SQLERRM,1,100));
返回HEXTORAW('EEEEEE');

我看到的唯一区别是使用PKCS5和PCKS7。但是,.NET没有PCKS5。

解决方案

什么abc说,你似乎没有任何IV初始化向量)在你的Unix代码中。



第一部分相同的事实与不同的模式(ECB和CBC)有关。 ECB分别加密每个块,而CBC在加密下一个块时使用上一个块。



这里发生的是因为您使用CBC而不设置IV,所以IV全为零。

这意味着第一个ECB加密和CBC加密将是一样的。

(由于A XOR 0 = A)。



您需要确保使用相同的加密模式在两个系统中,如果您决定使用CBC,请确保使用相同的IV。


I am using RijndaelManaged to make a simple encryption/decryption utility. This is working fine, but I am trying to get it integrated with another program which is created in Unix (Oracle). My problem is, for all smaller input string, i am getting the exact same encrypted hex as the Unix code is generation, but for longer strings, half of my encrypted hex is same, but the other half is different:

Unix Output:

012345678901234 - 00984BBED076541E051A239C02D97117
0123456789012345678 - A0ACE158AD8CF70CEAE8F76AA27F62A30EA409ECE2F7FF84F1A9AF50817FC0C4

Windows Output (my code):

012345678901234 - 00984BBED076541E051A239C02D97117 (same as above)
0123456789012345678 - A0ACE158AD8CF70CEAE8F76AA27F62A3D9A1B396A614DA2C1281AA1F48BC3EBB (half exactly same as above)

My Windows code is:

public string Encrypt(byte[] PlainTextBytes, byte[] KeyBytes, string InitialVector)
        {
            byte[] InitialVectorBytes = Encoding.ASCII.GetBytes(InitialVector);
            RijndaelManaged SymmetricKey = new RijndaelManaged();
            SymmetricKey.Mode = CipherMode.ECB;
            SymmetricKey.Padding = PaddingMode.PKCS7;
            ICryptoTransform Encryptor = SymmetricKey.CreateEncryptor(KeyBytes, InitialVectorBytes);
            MemoryStream MemStream = new MemoryStream();
            CryptoStream CryptoStream = new CryptoStream(MemStream, Encryptor, CryptoStreamMode.Write);
            CryptoStream.Write(PlainTextBytes, 0, PlainTextBytes.Length);
            CryptoStream.FlushFinalBlock();
            byte[] CipherTextBytes = MemStream.ToArray();
            MemStream.Close();
            CryptoStream.Close();
            return ByteToHexConversion(CipherTextBytes);
        }

Unix (PL/SQL) code:

FUNCTION Encrypt_Card (plain_card_id  VARCHAR2)
    RETURN RAW AS
        num_key_bytes      NUMBER := 256/8;        -- key length 256 bits (32 bytes)
        encrypted_raw      RAW (2000);             -- stores encrypted binary text
        encryption_type    PLS_INTEGER :=          -- total encryption type
                        DBMS_CRYPTO.ENCRYPT_AES256
                      + DBMS_CRYPTO.CHAIN_CBC
                      + DBMS_CRYPTO.PAD_PKCS5;

        key_bytes_raw  RAW(64) :=my_hex_key;
    BEGIN



     encrypted_raw := DBMS_CRYPTO.ENCRYPT
           (
              src => UTL_I18N.STRING_TO_RAW (plain_card_id, 'AL32UTF8'),
              typ => encryption_type,
              key => key_bytes_raw
           );


      RETURN encrypted_raw;
    EXCEPTION
    WHEN OTHERS THEN
    dbms_output.put_line (plain_card_id || ' - ' || SUBSTR(SQLERRM,1,100) );
    RETURN HEXTORAW ('EEEEEE');

The only difference i see is use of PKCS5 and PCKS7. But, .NET doesn't have PCKS5.

解决方案

What abc said and also you don't seem to have any IV (Initialization Vector) in you Unix code at all.

The fact that the first part are the same has to do with the different modes (ECB and CBC). ECB encrypts each block separately while CBC uses the previous block when encrypting the next one.

What happens here is that since you use CBC and do not set an IV the IV is all zeroes.
That means that the first block of ECB encryption and CBC encryption will be the same.
(Since A XOR 0 = A).

You need to make sure you use the same encryption mode in both systems and if you decide on CBC make sure you use the same IV.

这篇关于C#AES-256加密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-06 02:05