簡體   English   中英

c#AES解密

[英]c# AES decrypting

我試圖通過AES在C#中創建加密/解密程序。 這是我的代碼:

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

namespace encryptingApp
{
    public class AES_Crypt
    {
        public static void Main ()
        {
            string text = "this-needs-to-be-encrypted";

            string IV = "0000000000000000";

            int ivBlockSize = 16;

            string key = "00000000000000000000000000000000";

            int keySize = 32;

            string encriptedText = Encrypt(text,key,IV);

            string decrypted = Decrypt(encriptedText, key, ivBlockSize);

        }


        public static string Encrypt(string clearText, string key, string iv )
        {

            byte[] textBytes=GetBytes(clearText);


            using (Aes encryptor = Aes.Create())
            {
                encryptor.IV =  GetBytes(iv);
                encryptor.Key = GetBytes(key);

                using (MemoryStream ms = new MemoryStream())
                {

                    using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(encryptor.Key,encryptor.IV), CryptoStreamMode.Write))
                    {
                        cs.Write(textBytes, 0, textBytes.Length);
                        cs.Close();
                    }
                    string rv= iv + ByteToHex(ms.ToArray()).ToLower();

                    clearText = Base64Encode(rv);
                }
            }
            return clearText;
        }



       public static string Decrypt(string encriptedText, string key, int ivBlockSize)
       {
           string decryptedText = null;

           string fullText=Base64Decode(encriptedText);

           string realIV = fullText.Substring( 0 , ivBlockSize );

           string cypherText = fullText.Substring(ivBlockSize, fullText.Length - ivBlockSize - 1);


            byte[] cypherTextInBytes = HexToByte(cypherText);

            using (Aes decryptor = Aes.Create())
            {     
                decryptor.Key = GetBytes(key);

                decryptor.IV = GetBytes(realIV);

                decryptor.Mode = CipherMode.CBC;  

                using (MemoryStream ms = new MemoryStream())
                {
                    using (CryptoStream cs = new CryptoStream(ms, decryptor.CreateDecryptor(decryptor.Key,decryptor.IV), CryptoStreamMode.Read))
                    {
                        using (var sr = new StreamReader(cs))
                        {
                            decryptedText = sr.ReadToEnd();
                        }

                    }

                }
            }
            return decryptedText;
        }

        static byte[] GetBytes(string str)
        {
            return System.Text.Encoding.UTF8.GetBytes(str);
        }

        static string GetString(byte[] bytes)
        {
            return System.Text.Encoding.UTF8.GetString(bytes);
        }

        public static string Base64Encode(string plainText)
        {
                var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
                return System.Convert.ToBase64String(plainTextBytes);
        }

        public static string Base64Decode(string base64EncodedData)
        {
            var base64EncodedBytes = System.Convert.FromBase64String(base64EncodedData);
            return System.Text.Encoding.UTF8.GetString(base64EncodedBytes);
        }

        public static string ByteToHex(byte[] ba)
        {
            return BitConverter.ToString(ba).Replace("-", "").ToLower();
        }


        public static byte[] HexToByte(string hex)
        {

            byte[] arr = new byte[hex.Length >> 1];

            for (int i = 0; i < hex.Length >> 1; ++i)
            {
                arr[i] = (byte)((GetHexVal(hex[i << 1]) << 4) + (GetHexVal(hex[(i << 1) + 1])));
            }

            return arr;
        }

        public static int GetHexVal(char hex) 
        {
            int val = (int) hex;
            return val - (val < 58 ? 48 : 87);
        }


    }
}

加密功能很好地完成了他的工作,並返回正確的加密文本。 Decrypt函數中存在問題,一切順利(我一直在屏幕上打印我的變量),直到StreamReader使用.ReadToEnd()。 我得到一個CryptographyException(我只在一個exectuion中得到兩次相同的異常):

Unhandled Exception:
System.Security.Cryptography.CryptographicException: Bad PKCS7 padding. Invalid length 0.        
at Mono.Security.Cryptography.SymmetricTransform.ThrowBadPaddingException (System.Security.Cryptography.PaddingMode padding, System.Int32 length, System.Int32 position) [0x0005c] in <8f2c484307284b51944a1a13a14c0266>:0 
at Mono.Security.Cryptography.SymmetricTransform.FinalDecrypt (System.Byte[] inputBuffer, System.Int32 inputOffset, System.Int32 inputCount) [0x00179] in <8f2c484307284b51944a1a13a14c0266>:0 
at Mono.Security.Cryptography.SymmetricTransform.TransformFinalBlock (System.Byte[] inputBuffer, System.Int32 inputOffset, System.Int32 inputCount) [0x00034] in <8f2c484307284b51944a1a13a14c0266>:0 
at System.Security.Cryptography.CryptoStream.Read (System.Byte[] buffer, System.Int32 offset, System.Int32 count) [0x00318] in <8f2c484307284b51944a1a13a14c0266>:0 
at System.IO.StreamReader.ReadBuffer () [0x0002b] in <8f2c484307284b51944a1a13a14c0266>:0 
at System.IO.StreamReader.ReadToEnd () [0x00055] in <8f2c484307284b51944a1a13a14c0266>:0 
at encryptingApp.AES_Crypt.Decrypt (System.String encriptedText, System.String key, System.Int32 ivBlockSize) [0x000e4] in <f27b48dde1ea4b788e8038439b4bdb55>:0 
at encryptingApp.AES_Crypt.Main () [0x000e0] in <f27b48dde1ea4b788e8038439b4bdb55>:0


[ERROR] FATAL UNHANDLED EXCEPTION: System.Security.Cryptography.CryptographicException: Bad PKCS7 padding. Invalid length 0.    
at Mono.Security.Cryptography.SymmetricTransform.ThrowBadPaddingException (System.Security.Cryptography.PaddingMode padding, System.Int32 length, System.Int32 position) [0x0005c] in <8f2c484307284b51944a1a13a14c0266>:0 
at Mono.Security.Cryptography.SymmetricTransform.FinalDecrypt (System.Byte[] inputBuffer, System.Int32 inputOffset, System.Int32 inputCount) [0x00179] in <8f2c484307284b51944a1a13a14c0266>:0 
at Mono.Security.Cryptography.SymmetricTransform.TransformFinalBlock (System.Byte[] inputBuffer, System.Int32 inputOffset, System.Int32 inputCount) [0x00034] in <8f2c484307284b51944a1a13a14c0266>:0 
at System.Security.Cryptography.CryptoStream.FlushFinalBlock () [0x0001b] in <8f2c484307284b51944a1a13a14c0266>:0 
at System.Security.Cryptography.CryptoStream.Dispose (System.Boolean disposing) [0x00011] in <8f2c484307284b51944a1a13a14c0266>:0 
at System.IO.Stream.Close () [0x00000] in <8f2c484307284b51944a1a13a14c0266>:0 
at System.IO.StreamReader.Dispose (System.Boolean disposing) [0x0001c] in <8f2c484307284b51944a1a13a14c0266>:0 
at System.IO.TextReader.Dispose () [0x00000] in <8f2c484307284b51944a1a13a14c0266>:0 
at encryptingApp.AES_Crypt.Decrypt (System.String encriptedText, System.String key, System.Int32 ivBlockSize) [0x000f8] in <f27b48dde1ea4b788e8038439b4bdb55>:0 
at encryptingApp.AES_Crypt.Main () [0x000e0] in <f27b48dde1ea4b788e8038439b4bdb55>:0

我想我應該修復Streamreader,但我不知道該怎么做,我已經在這里待了幾個小時! 似乎該程序試圖讀取具有0長度或其他東西的東西。

我甚至嘗試在互聯網上尋找更多解密功能,但它們都不適合我(我這樣做沒有RijndaelManaged,也沒有鹽)。 我在MacOS編譯。

為什么代碼中有這么多字符串? 密碼術在字節上工作,擺脫所有字符串。

  • 你的IV(最好由Encrypt生成/發出,不傳入它)被讀作UTF-8字符串。 如果它有任何不在ASCII 0-127中的字符,則字節[]長度的字符串長度不會是1:1。
    • 使用iv 0x00000000000000000000000000000003提供字符串也很困難
  • 類似於你的鑰匙。
  • 您正在發出IV + Ciphertext blob Base64Encode(UTF8Bytes(Concat(ivString,Hex(ciphertextBytes))))。
    • Base64Encode(Concat(ivBytes,ciphertextBytes))涉及兩個較少的轉換。 因此它不易出錯,而且速度更快。
  • 當您進入Decrypt時,您可以正確應用所有變換以撤消已完成的操作,但您需要知道外部有多少字符構成IV。 由於您已將UTF8處理添加到混音中,因此您實際上並不知道它。
    • 所以你的Decrypt IV得到了以下治療
      • Base64Decode
      • UTF8BytesToString
      • UTF8StringToBytes
    • 如果沒有涉及字符串,你只需要Base64Decode和Copy。

我的直覺是,如果你只是將所有內容視為byte[]你的問題就會消失。 (是的,您要保護的數據可以是文本,因此直接使用UTF8StringToBytes命中它是好的)

暫無
暫無

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

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