bc-csharp
bc-csharp copied to clipboard
Securly overwrite BigInteger
I wanted to do some crypto with BigIntegers, but the it doesn't seem to be possible to delete them or securely overwrite them. Could you add such a method?
Wouldn't assigning null to the BigInteger after operations be enough?
I am using BigInteger to store key material and other sensitive data (so is bc-sharp). If I just derefernce the BigIntegers the garbage collector will mark the memory as free, but wont zero/overwrite it until it is allocated again ( if I understand that correctly). This means in theory it could be there indefinitely and since memory leaks exist, I would be a lot happier if I could just zero the underlying byte array
@schoenbornl you are right. Setting a reference type to null
means that it will be overwritten sometime in the future. However, BigInteger
is a struct, which means that setting it to a value overwrites the memory right away. You can just set it to 0. (Unless you're using the nullable version, i.e. BigInteger?
). What I am not sure about is whether all the underlying reference types get overwritten as well (the BigInteger
implementation uses an uint[]
to store data).
If you think about it, the sensitive data must be revealed in memory at some point in time in order to be used. An attacker would have the opportunity to read it anyways. The promise by GC that the data would be overwritten sometime in the future is enough, at least for my purposes.
@sorashi, bouncycastle big integer implementation (which I feel the issue author is referring to) is a class not a struct.
@sorashi, bouncycastle big integer implementation (which I feel the issue author is referring to) is a class not a struct.
ok, my fault
Interesting quote on the RSAParameters
documentation
RSAParameters is not encrypted in any way, so you must be careful when you use it with the private key information. In fact, none of the fields that contain private key information can be serialized. If you try to serialize an RSAParameters structure with a remoting call or by using one of the serializers, you will receive only public key information. If you want to pass private key information, you will have to manually send that data. In all cases, if anyone can derive the parameters, the key that you transmit becomes useless.
The purpose of RSA is to secure information during transmit, therefore the key privacy at the end-points is not so strict in most cases (there's usually symmetric encryption, but the key must get revealed when it's being used).
Just faced the same problem. Generally, .NET apps must store secrets in System.SecureString
or their own implementations of a similar concept.
Secrets should be stored in an unmanaged memory (because GC does not have to zero out the data during mark-sweep phase), and cleared out using SecureZeroMemory or a similar platform-specific function before being deallocated. Also, there should be a way to explicitly deallocate a secret as soon, as it is not needed anymore.
SecureString doesn't really work and is probably being deprecated (https://github.com/dotnet/runtime/issues/30612) but netcore should be getting support for safely zeroing secrets without pinning/unmanaged memory (https://github.com/dotnet/runtime/issues/10480)