简体   繁体   English

在C#中,为什么在内存中固定密钥更安全?

[英]In C#, why is pinning a secret key in memory more secure?

Microsoft's sample code for encryption / decryption in C# has an unexplained line where they pin the secret key in memory. 微软用于C#中加密/解密的示例代码有一条无法解释的行,它将密钥固定在内存中。 I understand the concept of pinning well enough - it's used to indicate the GC should not move the contents of that memory to other locations. 我理解钉扎的概念 - 它用于表示GC不应该将该内存的内容移动到其他位置。 Sure, fine. 当然,很好。

What's the benefit of pinning the secret key? 固定密钥有什么好处? I am fairly sure there is one - a very intelligent developer I worked with once upon a time mentioned that it was an important step for our software to be secure. 我很确定有一个 - 一个非常聪明的开发人员,曾经一度提到过,这是我们软件安全的重要一步。 The relevant code from MS's article . MS 文章中的相关代码。

static void Main()
{
    // Must be 64 bits, 8 bytes.
    // Distribute this key to the user who will decrypt this file.
    string sSecretKey;

    // Get the key for the file to encrypt.
    sSecretKey = GenerateKey();

    // For additional security pin the key.
    GCHandle gch = GCHandle.Alloc( sSecretKey, GCHandleType.Pinned );

    // Encrypt the file.        
    EncryptFile( @"C:\MyData.txt", @"C:\Encrypted.txt", sSecretKey );

    // Decrypt the file.
    DecryptFile( @"C:\Encrypted.txt", @"C:\Decrypted.txt", sSecretKey );

    // Remove the key from memory. 
    ZeroMemory( gch.AddrOfPinnedObject(), sSecretKey.Length * 2 );
    gch.Free();
}

It's because overwriting the memory only overwrites where the data is located now . 这是因为覆盖内存仅覆盖数据位于现在的位置。

If the garbage collector has moved it around, there could be copies of the data remaining in its prior locations. 如果垃圾收集器已将其移动,则可能存在其先前位置中剩余的数据的副本。

Why aren't you using the SecureString class for this? 你为什么不使用SecureString类呢? Overwriting a System.String in-place violates its invariants and could cause unexpected behavior. 就地覆盖System.String违反其不变量,并可能导致意外行为。 A SecureString however is designed to be erased and leave no copies behind. 然而, SecureString被设计为被删除并且不留下任何副本。

He's making it "more secure" by zero-ing out the memory after he's finished using it. 他在完成使用后将内存归零,使其“更加安全”。 You can't access the memory bytes directly unless you pin the object. 除非固定对象,否则无法直接访问内存字节。 If you don't zero out the bytes, the string will lay around in memory until the garbage collector gets around to cleaning it up. 如果你没有将字节清零,字符串将在内存中存在,直到垃圾收集器开始清理它。

Someone could read your process's memory and find the secret key there. 有人可以读取你的进程的内存并在那里找到密钥。 Granted, someone could still do that, there's just a smaller window of time where it's accessible. 当然,有人仍然可以这样做,只有一个较小的时间窗口可以访问。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM