簡體   English   中英

C# 從 Java AES/CBC/PKCS5Padding 加密/解密

[英]C# Encrypt/Decrypt from Java AES/CBC/PKCS5Padding

我在嘗試使用以下屬性(Java 代碼)解密在 Java 中加密的字符串時遇到問題

public static Builder getDefaultBuilder(String key, String salt, byte[] iv) {
        return new Builder()
                .setIv(iv)
                .setKey(key)
                .setSalt(salt)
                .setKeyLength(128)
                .setKeyAlgorithm("AES")
                .setCharsetName("UTF8")
                .setIterationCount(1)
                .setDigestAlgorithm("SHA1")
                .setBase64Mode(Base64.DEFAULT)
                .setAlgorithm("AES/CBC/PKCS5Padding")
                .setSecureRandomAlgorithm("SHA1PRNG")
                .setSecretKeyType("PBKDF2WithHmacSHA1");
    }

到目前為止,這是我的代碼(C#)

public string DecryptText(string encryptedString)
    {
        using (myRijndael = new RijndaelManaged())
        {
            myRijndael.Key = Convert.FromBase64String(encryptionKey);
            myRijndael.IV = new byte[16];
            myRijndael.Mode = CipherMode.CBC;
            myRijndael.Padding = PaddingMode.PKCS7;

            Byte[] ourEnc = Convert.FromBase64String(encryptedString);
            string ourDec = DecryptStringFromBytes(ourEnc, myRijndael.Key, myRijndael.IV);

            return ourDec;
        }
    }

protected string DecryptStringFromBytes(byte[] cipherText, byte[] Key, byte[] IV)
    {
        // Check arguments. 
        if (cipherText == null || cipherText.Length <= 0)
            throw new ArgumentNullException("cipherText");
        if (Key == null || Key.Length <= 0)
            throw new ArgumentNullException("Key");
        if (IV == null || IV.Length <= 0)
            throw new ArgumentNullException("Key");

        // Declare the string used to hold 
        // the decrypted text. 
        string plaintext = null;

        // Create an RijndaelManaged object 
        // with the specified key and IV. 
        using (RijndaelManaged rijAlg = new RijndaelManaged())
        {
            rijAlg.Key = Key;
            rijAlg.IV = IV;

            // Create a decrytor to perform the stream transform.
            ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);

            // Create the streams used for decryption. 
            using (MemoryStream msDecrypt = new MemoryStream(cipherText))
            {
                using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                {
                    using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                    {

                        // Read the decrypted bytes from the decrypting stream 
                        // and place them in a string.
                        plaintext = srDecrypt.ReadToEnd();
                    }
                }
            }

        }

        return plaintext;

    }

但是,當我嘗試解密時,出現以下異常“System.Security.Cryptography.CryptographicException: 'Specified key is not a valid size for this algorithm.' ”。

Java 代碼的來源在這里https://github.com/simbiose/Encryption/blob/master/Encryption/main/se/simbio/encryption/Encryption.java

這是加密時的Java代碼

public String encrypt(String data) throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeyException, InvalidKeySpecException, BadPaddingException, IllegalBlockSizeException {
    if (data == null) return null;
    SecretKey secretKey = getSecretKey(hashTheKey(mBuilder.getKey()));
    byte[] dataBytes = data.getBytes(mBuilder.getCharsetName());
    Cipher cipher = Cipher.getInstance(mBuilder.getAlgorithm());
    cipher.init(Cipher.ENCRYPT_MODE, secretKey, mBuilder.getIvParameterSpec(), mBuilder.getSecureRandom());
    return Base64.encodeToString(cipher.doFinal(dataBytes), mBuilder.getBase64Mode());
}

private SecretKey getSecretKey(char[] key) throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeySpecException {
    SecretKeyFactory factory = SecretKeyFactory.getInstance(mBuilder.getSecretKeyType());
    KeySpec spec = new PBEKeySpec(key, mBuilder.getSalt().getBytes(mBuilder.getCharsetName()), mBuilder.getIterationCount(), mBuilder.getKeyLength());
    SecretKey tmp = factory.generateSecret(spec);
    return new SecretKeySpec(tmp.getEncoded(), mBuilder.getKeyAlgorithm());
}


private char[] hashTheKey(String key) throws UnsupportedEncodingException, NoSuchAlgorithmException {
    MessageDigest messageDigest = MessageDigest.getInstance(mBuilder.getDigestAlgorithm());
    messageDigest.update(key.getBytes(mBuilder.getCharsetName()));
    return Base64.encodeToString(messageDigest.digest(), Base64.NO_PADDING).toCharArray();
}

我已經為此苦苦掙扎了兩天,因為我並沒有真正在加密方面工作過很多,所以任何幫助將不勝感激。

謝謝!

更新:全班

public sealed class MyCryptoClass
{
    protected RijndaelManaged myRijndael;

    private static string encryptionKey = "random";

    // Singleton pattern used here with ensured thread safety
    protected static readonly MyCryptoClass _instance = new MyCryptoClass();
    public static MyCryptoClass Instance
    {
        get { return _instance; }
    }

    public MyCryptoClass()
    {

    }

    public string DecryptText(string encryptedString)
    {
        using (myRijndael = new RijndaelManaged())
        {
            myRijndael.Key = Convert.FromBase64String(encryptionKey);
            myRijndael.IV = new byte[16];
            myRijndael.Mode = CipherMode.CBC;
            myRijndael.Padding = PaddingMode.PKCS7;

            Byte[] ourEnc = Convert.FromBase64String(encryptedString);
            string ourDec = DecryptStringFromBytes(ourEnc, myRijndael.Key, myRijndael.IV);

            return ourDec;
        }
    }


    public string EncryptText(string plainText)
    {
        using (myRijndael = new RijndaelManaged())
        {

            myRijndael.Key = HexStringToByte(encryptionKey);
            myRijndael.IV = HexStringToByte(initialisationVector);
            myRijndael.Mode = CipherMode.CBC;
            myRijndael.Padding = PaddingMode.PKCS7;

            byte[] encrypted = EncryptStringToBytes(plainText, myRijndael.Key, myRijndael.IV);
            string encString = Convert.ToBase64String(encrypted);

            return encString;
        }
    }


    protected byte[] EncryptStringToBytes(string plainText, byte[] Key, byte[] IV)
    {
        // Check arguments. 
        if (plainText == null || plainText.Length <= 0)
            throw new ArgumentNullException("plainText");
        if (Key == null || Key.Length <= 0)
            throw new ArgumentNullException("Key");
        if (IV == null || IV.Length <= 0)
            throw new ArgumentNullException("Key");
        byte[] encrypted;
        // Create an RijndaelManaged object 
        // with the specified key and IV. 
        using (RijndaelManaged rijAlg = new RijndaelManaged())
        {
            rijAlg.Key = Key;
            rijAlg.IV = IV;

            // Create a decrytor to perform the stream transform.
            ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);

            // Create the streams used for encryption. 
            using (MemoryStream msEncrypt = new MemoryStream())
            {
                using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                {
                    using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                    {

                        //Write all data to the stream.
                        swEncrypt.Write(plainText);
                    }
                    encrypted = msEncrypt.ToArray();
                }
            }
        }


        // Return the encrypted bytes from the memory stream. 
        return encrypted;

    }

    protected string DecryptStringFromBytes(byte[] cipherText, byte[] Key, byte[] IV)
    {
        // Check arguments. 
        if (cipherText == null || cipherText.Length <= 0)
            throw new ArgumentNullException("cipherText");
        if (Key == null || Key.Length <= 0)
            throw new ArgumentNullException("Key");
        if (IV == null || IV.Length <= 0)
            throw new ArgumentNullException("Key");

        // Declare the string used to hold 
        // the decrypted text. 
        string plaintext = null;

        // Create an RijndaelManaged object 
        // with the specified key and IV. 
        using (RijndaelManaged rijAlg = new RijndaelManaged())
        {
            rijAlg.Key = Key;
            rijAlg.IV = IV;

            // Create a decrytor to perform the stream transform.
            ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);

            // Create the streams used for decryption. 
            using (MemoryStream msDecrypt = new MemoryStream(cipherText))
            {
                using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                {
                    using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                    {

                        // Read the decrypted bytes from the decrypting stream 
                        // and place them in a string.
                        plaintext = srDecrypt.ReadToEnd();
                    }
                }
            }

        }

        return plaintext;

    }

    public static void GenerateKeyAndIV()
    {
        // This code is only here for an example
        RijndaelManaged myRijndaelManaged = new RijndaelManaged();
        myRijndaelManaged.Mode = CipherMode.CBC;
        myRijndaelManaged.Padding = PaddingMode.PKCS7;

        myRijndaelManaged.GenerateIV();
        myRijndaelManaged.GenerateKey();
        string newKey = ByteArrayToHexString(myRijndaelManaged.Key);
        string newinitVector = ByteArrayToHexString(myRijndaelManaged.IV);
    }

    protected static byte[] HexStringToByte(string hexString)
    {
        try
        {
            int bytesCount = (hexString.Length) / 2;
            byte[] bytes = new byte[bytesCount];
            for (int x = 0; x < bytesCount; ++x)
            {
                bytes[x] = Convert.ToByte(hexString.Substring(x * 2, 2), 16);
            }
            return bytes;
        }
        catch
        {
            throw;
        }
    }

    public static string ByteArrayToHexString(byte[] ba)
    {
        StringBuilder hex = new StringBuilder(ba.Length * 2);
        foreach (byte b in ba)
            hex.AppendFormat("{0:x2}", b);
        return hex.ToString();
    }
}
  • 由於您的MyCryptoClass.encryptionKey對應於您的Encryption.Builder.mKey您必須在 C# 端生成密鑰,即您必須在 C# 端為該過程中涉及的每個 Java 方法實現一個對應物。 這些 Java 方法是getSecretKey(char[] key)hashTheKey(String key)third.part.android.util.Base64.encodeToString(byte[] input, int flags)

  • Java 方法getSecretKey(char[] key)可能 C# 對應部分:

     private static byte[] GetSecretKey() { string hashedKey = GetHashedKey(); byte[] saltBytes = Encoding.UTF8.GetBytes(salt); // builder.mCharsetName = "UTF8"; int iterations = 1; // builder.mIterationCount = 1 byte[] secretKey = null; using (Rfc2898DeriveBytes rfc2898 = new Rfc2898DeriveBytes(hashedKey, saltBytes, iterations)) // builder.mSecretKeyType = "PBKDF2WithHmacSHA1"; { secretKey = rfc2898.GetBytes(16); // builder.mKeyLength = 128; //Console.WriteLine("Key: " + ByteArrayToHexString(secretKey)); } return secretKey; }

    此方法使用PBKDF2WithHmacSHA1以密鑰、salt、迭代次數和密鑰長度作為輸入來派生密鑰。 這里使用的密鑰(更精確地密碼)是一個64位編碼SHA1散列MyCryptoClass.encryptionKey提供GetHashedKey()見下文)。

  • Java 方法hashTheKey(String key)可能的 C#-Counterpart :

     private static string GetHashedKey() { string hashBase64 = String.Empty; using (SHA1Managed sha1 = new SHA1Managed()) // builder.mDigestAlgorithm = "SHA1"; { byte[] hash = sha1.ComputeHash(Encoding.UTF8.GetBytes(encryptionKey)); // builder.mCharsetName = "UTF8"; hashBase64 = Base64ThirdPartAndroid(hash, true); //Console.WriteLine("Hash (base64): " + hashBase64); } return hashBase64; }

    此方法從MyCryptoClass.encryptionKey和 base64 編碼該哈希派生SHA1哈希。 對於 base64 編碼,使用方法Base64ThirdPartAndroid(byte[] arr, bool withoutPadding) (見下文)。

  • Java方法的可能的C#-Counterpartthird.part.android.util.Base64.encodeToString third.part.android.util.Base64.encodeToString(byte[] input, int flags) ( https://github.com/simbiose/Encryption/blob/master/Encryption/main/第三/部分/android/util/Base64.java ):

     private static string Base64ThirdPartAndroid(byte[] arr, bool withoutPadding) { string base64String = System.Convert.ToBase64String(arr); if (withoutPadding) base64String = base64String.TrimEnd('='); // Remove trailing "="-characters base64String += "\\n"; // Append LF (10) //Console.WriteLine("Array as base64 encoded string: " + base64String); return base64String; }

    在 Java 代碼中, third.part.android.util.Base64.encodeToString(byte[] input, int flags)flags = Base64.NO_PADDING一起使用,它刪除了 base64 編碼字符串末尾的“=”字符。 此外,還附加了換行符(LF、 \\n 、ASCII 值:10)。 如果使用 Base64-Encoding 不會刪除“=”字符或沒有終止換行符,則解密將失敗,因為哈希是后來生成的密鑰的基礎,必須與加密和解密端。 據我所知,C# 端沒有具有必要特征的 Base64 編碼。 但是,如果有這樣的編碼,您當然可以使用它。

  • 將所有三個 C# 對應物添加到您的MyCryptoClass class

  • 另外(與靜態磁場encryptionKey )添加靜態字段initialisationVectorsaltsecretKeyMyCryptoClass -class並指定用於測試目的以下值:

     private static string encryptionKey = "A7zb534OPq59gU7q"; private static string salt = "JV5k9GoH"; private static byte[] initialisationVector = Encoding.UTF8.GetBytes("l4iG63jN9Dcg6537"); private static byte[] secretKey = GetSecretKey();

    參數的類型對應於 Java 代碼中的類型( encryptionKeysalt是字符串, initialisationVector是一個字節數組)。 GetSecretKey()生成的密鑰存儲在字節數組secretKey

  • 在您的 C# DecryptText - 和EncryptText -method 中,將myRijndael.KeymyRijndael.IV設置為

    myRijndael.Key = secretKey; myRijndael.IV = initialisationVector;
  • 測試修改如下:

    • 使用您的 Java encrypt -方法加密以下純文本:

       Test: The quick brown fox jumps over the lazy dog...

      使用上面的 key/salt/iv

       mBuilder = Builder.getDefaultBuilder("A7zb534OPq59gU7q","JV5k9GoH","l4iG63jN9Dcg6537".getBytes("UTF-8"));
    • 加密后的文本是:

       mL4ajZtdRgD8CtGSfJGkT24Ebw4SrGUGKQI6bvBw1ziCO/J7SeLiyIw41zumTHMMD9GOYK+kR79CVcpoaHT9TQ==
    • 使用 C# DecryptText -method 解密它再次給出純文本。 下面是兩個測試用例:

       static void Main(string[] args) { // Test 1: Encrypted text from C# MyCryptoClass mcc = MyCryptoClass.Instance; string encryptedText = mcc.EncryptText("This is a plain text which needs to be encrypted..."); Console.WriteLine("Encrypted text (base64): " + encryptedText); string decryptedText = mcc.DecryptText(encryptedText); Console.WriteLine("Decrypted text: " + decryptedText); // Test 2: Encrypted text from Java string javaEncryptedText = "mL4ajZtdRgD8CtGSfJGkT24Ebw4SrGUGKQI6bvBw1ziCO/J7SeLiyIw41zumTHMMD9GOYK+kR79CVcpoaHT9TQ=="; Console.WriteLine("Encrypted text from Java (base64): " + javaEncryptedText); string javaDecryptedText = mcc.DecryptText(javaEncryptedText); Console.WriteLine("Decrypted text from Java: " + javaDecryptedText); }

以下是完整的 C# 類,我可以像 java 類一樣工作,目前我只檢查了加密部分

 public sealed class MyCryptoClass
    {
        protected AesManaged myRijndael;

        private static string encryptionKey = "MyKey";
        private static string salt = "Mysalt";
        private static byte[] initialisationVector = new byte[16];
        //private static byte[] initialisationVector = Encoding.UTF8.GetBytes("l4iG63jN9Dcg6537");
        private static byte[] secretKey = GetSecretKey();


        // Singleton pattern used here with ensured thread safety
        protected static readonly MyCryptoClass _instance = new MyCryptoClass();
        public static MyCryptoClass Instance
        {
            get { return _instance; }
        }

        public MyCryptoClass()
        {

        }
        public string DecryptText(string encryptedString)
        {
            using (myRijndael = new AesManaged())
            {
                myRijndael.Key = Convert.FromBase64String(encryptionKey);
                myRijndael.IV = new byte[16];
                myRijndael.Mode = CipherMode.CBC;
                myRijndael.Padding = PaddingMode.PKCS7;

                Byte[] ourEnc = Convert.FromBase64String(encryptedString);
                string ourDec = DecryptStringFromBytes(ourEnc, myRijndael.Key, myRijndael.IV);

                return ourDec;
            }
        }
        public string EncryptText(string plainText)
        {
            using (myRijndael = new AesManaged())
            {

                myRijndael.Key = secretKey;
                myRijndael.IV = initialisationVector;
                myRijndael.Mode = CipherMode.CBC;
                myRijndael.Padding = PaddingMode.PKCS7;

                byte[] encrypted = EncryptStringToBytes(plainText, myRijndael.Key, myRijndael.IV);
                string encString = Convert.ToBase64String(encrypted);

                return encString;
            }
        }
        protected byte[] EncryptStringToBytes(string plainText, byte[] Key, byte[] IV)
        {
            // Check arguments. 
            if (plainText == null || plainText.Length <= 0)
                throw new ArgumentNullException("plainText");
            if (Key == null || Key.Length <= 0)
                throw new ArgumentNullException("Key");
            if (IV == null || IV.Length <= 0)
                throw new ArgumentNullException("Key");
            byte[] encrypted;
            // Create an RijndaelManaged object 
            // with the specified key and IV. 
            using (RijndaelManaged rijAlg = new RijndaelManaged())
            {
                rijAlg.Key = Key;
                rijAlg.IV = IV;

                // Create a decrytor to perform the stream transform.
                ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);

                // Create the streams used for encryption. 
                using (MemoryStream msEncrypt = new MemoryStream())
                {
                    using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                    {
                        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                        {

                            //Write all data to the stream.
                            swEncrypt.Write(plainText);
                        }
                        encrypted = msEncrypt.ToArray();
                    }
                }
            }
            // Return the encrypted bytes from the memory stream. 
            return encrypted;

        }
        protected string DecryptStringFromBytes(byte[] cipherText, byte[] Key, byte[] IV)
        {
            // Check arguments. 
            if (cipherText == null || cipherText.Length <= 0)
                throw new ArgumentNullException("cipherText");
            if (Key == null || Key.Length <= 0)
                throw new ArgumentNullException("Key");
            if (IV == null || IV.Length <= 0)
                throw new ArgumentNullException("Key");

            // Declare the string used to hold 
            // the decrypted text. 
            string plaintext = null;

            // Create an RijndaelManaged object 
            // with the specified key and IV. 
            using (RijndaelManaged rijAlg = new RijndaelManaged())
            {
                rijAlg.Key = Key;
                rijAlg.IV = IV;

                // Create a decrytor to perform the stream transform.
                ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);

                // Create the streams used for decryption. 
                using (MemoryStream msDecrypt = new MemoryStream(cipherText))
                {
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                        {

                            // Read the decrypted bytes from the decrypting stream 
                            // and place them in a string.
                            plaintext = srDecrypt.ReadToEnd();
                        }
                    }
                }
            }
            return plaintext;
        }

        public static void GenerateKeyAndIV()
        {
            // This code is only here for an example
            AesManaged myRijndaelManaged = new AesManaged();
            myRijndaelManaged.Mode = CipherMode.CBC;
            myRijndaelManaged.Padding = PaddingMode.PKCS7;

            myRijndaelManaged.GenerateIV();
            myRijndaelManaged.GenerateKey();
            string newKey = ByteArrayToHexString(myRijndaelManaged.Key);
            string newinitVector = ByteArrayToHexString(myRijndaelManaged.IV);
        }

        protected static byte[] HexStringToByte(string hexString)
        {
            try
            {
                int bytesCount = (hexString.Length) / 2;
                byte[] bytes = new byte[bytesCount];
                for (int x = 0; x < bytesCount; ++x)
                {
                    bytes[x] = Convert.ToByte(hexString.Substring(x * 2, 2), 16);
                }
                return bytes;
            }
            catch
            {
                throw;
            }
        }

        public static string ByteArrayToHexString(byte[] ba)
        {
            StringBuilder hex = new StringBuilder(ba.Length * 2);
            foreach (byte b in ba)
                hex.AppendFormat("{0:x2}", b);
            return hex.ToString();
        }

        private static byte[] GetSecretKey()
        {
            string hashedKey = GetHashedKey();
            byte[] saltBytes = Encoding.UTF8.GetBytes(salt); // builder.mCharsetName = "UTF8";
            int iterations = 1; // builder.mIterationCount = 1
            byte[] secretKey = null;
            using (Rfc2898DeriveBytes rfc2898 = new Rfc2898DeriveBytes(hashedKey, saltBytes, iterations)) // builder.mSecretKeyType = "PBKDF2WithHmacSHA1";
            {
                secretKey = rfc2898.GetBytes(16); // builder.mKeyLength = 128;
                //Console.WriteLine("Key: " + ByteArrayToHexString(secretKey));
            }
            return secretKey;
        }

        private static string GetHashedKey()
        {
            string hashBase64 = String.Empty;
            using (SHA1Managed sha1 = new SHA1Managed()) // builder.mDigestAlgorithm = "SHA1";
            {
                byte[] hash = sha1.ComputeHash(Encoding.UTF8.GetBytes(encryptionKey)); // builder.mCharsetName = "UTF8";

                hashBase64 = Base64ThirdPartAndroid(hash, true);
                //hashBase64 = Base64ThirdPartAndroid(hash, true);
                //Console.WriteLine("Hash (base64): " + hashBase64);
            }
            return hashBase64;
        }

        private static string Base64ThirdPartAndroid(byte[] arr, bool withoutPadding)
        {
            string base64String = System.Convert.ToBase64String(arr);
            if (withoutPadding) base64String = base64String.TrimEnd('='); // Remove trailing "="-characters
            base64String += "\n"; // Append LF (10)
            //Console.WriteLine("Array as base64 encoded string: " + base64String);
            return base64String;
        }
    }

此方法 100% 適用於加密

public static string AESDecrypt(string text, string secretKey)
        {
            try
            {
                SHA1 sha = new SHA1CryptoServiceProvider();
                RijndaelManaged aes = new RijndaelManaged();

                byte[] finalKey = new byte[16]; // Used to generate finalKey
                byte[] byteDataToDecrypt = Convert.FromBase64String(text); // Converting Base64 data to Byte Array
                byte[] byteSecretKey = Encoding.UTF8.GetBytes(secretKey); // Converting secret key in byte array
                byte[] hashSecretKey = sha.ComputeHash(byteSecretKey); // geneating hash in byte array of secret key

                Array.Copy(hashSecretKey, finalKey, 16); // copying fist 16 bytes from hashed secret key to finaly key which to use in algo

                aes.KeySize = 128;
                aes.Padding = PaddingMode.PKCS7;
                aes.Mode = CipherMode.ECB;
                aes.Key = finalKey;

                using (ICryptoTransform decrypt = aes.CreateDecryptor(aes.Key, null)) //Passing IV as NULL because IV is not present in the Java Code
                {
                    byte[] dest = decrypt.TransformFinalBlock(byteDataToDecrypt, 0, byteDataToDecrypt.Length);
                    decrypt.Dispose();
                    return Encoding.UTF8.GetString(dest);
                }
            }
            catch (Exception ex)
            {

                throw ex;
            }

        }

暫無
暫無

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

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