簡體   English   中英

加密和解密字節數組

[英]encrypting and decrypting a byte array

我有以下實用程序函數將我的對象序列化為加密的字節數組,並從解密的字節數組反序列化

//encryption key
public static byte[] Key = new byte[]{0x43, 0x72, 0x6e, 0x6d, 0x54, 0x4d, 0x65,
                                      0x94, 0x16, 0x32, 0x44, 0x84, 0x7e, 0x18,
                                      0x64, 0x76, 0x6e, 0x63, 0x64, 0x7a, 0x5f,
                                      0x84, 0x7f, 0x9a};

//Decrypt byte[]
public static byte[] Decrypt(byte[] data)
{
    MemoryStream ms = new MemoryStream();
    Rijndael alg = Rijndael.Create();
    alg.Key = Key;
    CryptoStream cs = new CryptoStream(ms,
    alg.CreateDecryptor(), CryptoStreamMode.Write);
    cs.Write(data, 0, data.Length);
    cs.Close();
    byte[] decryptedData = ms.ToArray();
    return decryptedData;
}

//Encrypt byte[]
public static byte[] Encrypt(byte[] data)
{
    MemoryStream ms = new MemoryStream();
    Rijndael alg = Rijndael.Create();
    alg.Key = Key;
    CryptoStream cs = new CryptoStream(ms,
    alg.CreateEncryptor(), CryptoStreamMode.Write);
    cs.Write(data, 0, data.Length);
    cs.Close();
    byte[] encryptedData = ms.ToArray();
    return encryptedData;
}

//serialize object to memory stream
public static MemoryStream SerializeToStream(object o)
{
    MemoryStream stream = new MemoryStream();
    IFormatter formatter = new BinaryFormatter();
    formatter.Serialize(stream, o);
    return stream;
}

//deserialize object from memory stream
public static T DerializeFromStream<T>(MemoryStream memoryStream) where T : new()
{
    if (memoryStream == null) { return new T(); }
    T o;
    BinaryFormatter binaryFormatter = new BinaryFormatter();
    using (memoryStream)
    {
        memoryStream.Seek(0, SeekOrigin.Begin);
        o = (T)binaryFormatter.Deserialize(memoryStream);
    }
    return o;
}

這是使用上述實用功能的測試

//serialize to stream then to byte array
var obj = new SomeObject();
var bytes = SerializeToStream(obj).ToArray();
bytes = Encrypt(bytes);

//deserialize to decrypted byte array then to stream then to object
var memoryStream = new MemoryStream();
var Decryptedbytearray = Decrypt(bytes);
//fille the stream
memoryStream.Write(Decryptedbytearray, 0, Decryptedbytearray.Length);
//deserialize the object from the stream
//it fails here giving an exception saying the binary data is not valid
var obj2 = DerializeFromStream<SomeObject>(memoryStream);

反序列化對象時出現問題,請參閱注釋的最后一行,我做錯了什么?

如果您調試代碼,您將看到它沒有正確解密。 原因是,你必須使用不僅同樣key ,也是同樣的IV

來自MSDN

每當您創建其中一個SymmetricAlgorithm類的新實例或手動調用GenerateIV方法時,IV屬性都會自動設置為新的隨機值 IV屬性的大小必須與BlockSize屬性除以8相同。

請查看此問題 ,了解有關如何從密碼短語創建密鑰和IV的詳細信息。

有一種簡單的方法可以生成字節數組的加密版本。

看看這個代碼是安全Baseclass的一部分,它被設計為對數組的訪問權限有限,這個代碼在實例級別進行加密。 在查看它時,您會明白實際上當您更改“鹽”時,您可以非常輕松地更改范圍。 我抓住了錯誤,並沒有提出它們,這可以被認為是錯誤的編碼但是提供錯誤使黑客更容易理解如何通過你想要保護的東西......,這里是代碼:

internal class Protected
{
    private  Byte[] salt = Guid.NewGuid().ToByteArray();

    protected byte[] Protect(byte[] data)
    {
        try
        {
            return ProtectedData.Protect(data, salt, DataProtectionScope.CurrentUser);
        }
        catch (CryptographicException)//no reason for hackers to know it failed
        {
#if DEBUG
            throw;
#else
            return null;
#endif
        }
    }

    protected byte[] Unprotect(byte[] data)
    {
        try
        {
            return ProtectedData.Unprotect(data, salt, DataProtectionScope.CurrentUser);
        }
        catch (CryptographicException)//no reason for hackers to know it failed
        {
#if DEBUG
            throw;
#else
            return null;
#endif
        }
    }
}

ProtectedData類來自命名空間System.Security.Cryptography,可以在Core 2.0中的NuGet包System.Security.Cryptography.ProtectedData中找到

暫無
暫無

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

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