簡體   English   中英

Rijndael encrypter:獲取空字節[]。 不加密任何東西

[英]Rijndael encrypter: Getting empty byte[]. Not encrypting anything

晚上好!

我正在嘗試使用Rijndael算法和c#中的Rijndael類來實現加密器。 我試圖跟隨(不完全相同的代碼)下面的鏈接,但問題是給一個字符串加密我沒有得到任何結果。 我也沒有收到任何錯誤消息。

https://docs.microsoft.com/pt-br/dotnet/api/system.security.cryptography.rijndael?view=netframework-4.8

CryptDecrypt.cs

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace RijndaelAlgorithm {
    public class CryptDecrypt {
        private Byte[] iv;
        private Byte[] key; 

        public CryptDecrypt(String key) {
            iv = new Byte[] {21, 10, 21, 251, 132, 76, 121, 27, 210, 81, 215, 99, 14, 235, 11, 75};
            this.key = Encoding.ASCII.GetBytes(key);
        }

        public String encryptMsg(String originalMsg) {
            byte[] encryptedMsg;

            Rijndael rijAlg = Rijndael.Create();
            rijAlg.Key = formatKey();
            rijAlg.IV = iv;

            MemoryStream msEncrypt = new MemoryStream();
            ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);
            CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write);

            StreamWriter swEncrypt = new StreamWriter(csEncrypt);
            swEncrypt.Write(originalMsg);

            encryptedMsg = msEncrypt.ToArray();
            Console.WriteLine("encryptedMsg.Length: " + encryptedMsg.Length);

            return Convert.ToBase64String(encryptedMsg, 0, encryptedMsg.Length);
        }

        private Byte[] formatKey() {
            int len = key.Length;

            String strKey = System.Text.Encoding.UTF8.GetString(key);
            String fillKey = "";
            String strFormatedKey = "";

            Byte[] formatedKeyByte;

            if (len < 16)
                fillKey = new String('X',(16 - len));

            strFormatedKey = String.Concat(strKey, fillKey);
            formatedKeyByte = Encoding.ASCII.GetBytes(strFormatedKey);

            return formatedKeyByte;
        }
    }
}

Menu.cs

using System;

namespace RijndaelAlgorithm {
    public class Menu {
        private CryptDecrypt r;

        public Menu() {
            r = new CryptDecrypt("123654");
        }

        public void showMenu() {
            Console.WriteLine("the encrypted message is: " + r.encryptMsg("isjustatest"));
        }
    }
}

您似乎想要使用.NET應用程序加密消息,並希望獲得與您在其中一條評論中提到的特定在線服務相同的加密字節。

參數

加密的一個參數是初始化矢量(IV)。 它應該是隨機的並且只使用一次。 因此,如果兩個應用程序正確實現(具有不同的隨機IV),則加密的字節是不同的。

即使您使用相同的輸入,每次按鍵時此服務都會返回不同的結果。

但是,如果您通常采用不同的加密結果並使用相同的密鑰對其進行解密,則會返回原始字節。

使用此特定服務進行測試的下一個問題是,它們始終提供相同的前綴base64序列'U2FsdGVkX1'。 這不是標准的AES輸出(如果您解碼此base64序列,則會獲得'Salted_P')。 因此,使用不同的在線服務進行測試是有意義的。

因此,如果兩個AES-256編碼實現使用相同的參數,我們將獲得相同的編碼結果。 我們需要它:

  • 密鑰(32字節,AES-256不是16)
  • IV(16字節)

說到密鑰長度:正如評論中提到的其他人一樣,你不應該簡單地添加“X”或類似的東西,而是使用標准的加密機制來獲得一個好的密鑰。

方便測試的是將十六進制字符串轉換為字節數組並返回的方法,例如,請參閱這個很酷的答案中的StringToByteArray和ByteArrayToString方法: https//stackoverflow.com/a/311179

試一試吧。 如果我們把你的消息'isjustatest'帶有十六進制字符串'69736a7573746174657374374',我們需要一個32字節密鑰用於AES-256和16字節IV。

正如評論中提到的其他人一樣,您需要刷新並關閉流(或者更好的是,使用'using'語句)。

獲取代碼並更改密鑰和iv分配並將加密的消息輸出到控制台:

rijAlg.Key = StringToByteArray("519C7C3402A943D8AF83746C1548E475319EBDA6A38046059F83B21709BD6A5B"); //32 bytes
rijAlg.IV =  StringToByteArray("0D024CF947CE4C288880D0B34D29BFA5"); // 16 bytes
...
swEncrypt.Write(originalMsg);
swEncrypt.Flush();
swEncrypt.Close();
...
Console.WriteLine("encrypted bytes: '" + ByteArrayToString(encryptedMsg) + "'");

這導致在調試控制台中輸出'419536f27da3406625b2d07f43833aab'。

所以現在我們可以使用在線服務,例如https://cryptii.com/pipes/aes-encryption ,我們可以在其中輸入輸入數據,選擇加密算法,提供密鑰和IV字節,然后我們得到與您的相同的結果程序,請看這里的截圖:

在此輸入圖像描述

如上所述,在實際應用中使用它時,不要忘記使用不同的隨機IV。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM