Different values on encryption using the same container

1k views Asked by At

I have 2 Projects in the same solution, in one project I encrypt a message using SignData and in the other project I am recreating the message that was encrypted in the first project and I compare the results to see if they are the same. But the encryption from the first project doesn't return the same value like the encryption from the second project. How can I make so that if i give the same byte array in both the projects I get the same value returned. I think that RSA generates 2 different keys but I use the same container

param.KeyContainerName = "SignatureContainer101";

Is there any way that I can do this without passing any Key? I need it to run locally on the same machine. Or any other suggestions in what I can do to get the same result? This is the code I am using:

public static byte[] SignData(byte[] message)
    {

        //convert data to be signed in a byte array
        byte[] byteSignature2;

        CspParameters param = new CspParameters();
        //Giving container a name, so we can use the same keys for verifying data.
        param.KeyContainerName = "SignatureContainer101";

        //Initializing RSACryptoServiceProvider
        using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(param))
        {
            //We want RSACryptoServiceProvider to save keys in keystore
            //because we want to keep signature generation routine seperate
            //from verifying data against signature.
            rsa.PersistKeyInCsp = true;
            byte[] byteSignature = rsa.SignData(message, "SHA256");
            byteSignature2 = new byte[byteSignature.Length];
            byteSignature2 = byteSignature;



        }
        return byteSignature2;
    }
    public static bool VerifyData(byte[] originalMessage, byte[] signedMessage)
    {

        bool isSuccess = false;

        CspParameters param = new CspParameters();
        //Utilizing the same key container which was created during
        //signature generation process i.e. in GetDataSignature(string data) function.
        //If we don't utilize the same keycontainer, VerifyData will always return false
        //because RSACryptoSeriveProvider initialization will generate new keys.
        param.KeyContainerName = "SignatureContainer101";

        //Initializing RSACryptoServiceProvider
        using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(param))
        {

            //verifying data against signature
            isSuccess = rsa.VerifyData(originalMessage, "SHA256", signedMessage);
        }
        return isSuccess;
    }
}
2

There are 2 answers

1
Mohammad Mirmostafa On

I found no problem in you code. It works! This is what I've done:

public partial class Program
{
    protected override void Execute()
    {
        var message1 = Encoding.UTF8.GetBytes("Hello there,");
        var message2 = Encoding.UTF8.GetBytes("Hello there");
        var signed = SignData(message1);
        var notOK = VerifyData(message2, signed);
        var oK = VerifyData(message1, signed);
    }

    public static byte[] SignData(byte[] message)
    {
        byte[] byteSignature2;

        var param = new CspParameters
                    {
                        KeyContainerName = "SignatureContainer101"
                    };
        using (var rsa = new RSACryptoServiceProvider(param))
        {
            rsa.PersistKeyInCsp = true;
            var byteSignature = rsa.SignData(message, "SHA256");
            byteSignature2 = byteSignature;
        }
        return byteSignature2;
    }
    public static bool VerifyData(byte[] originalMessage, byte[] signedMessage)
    {
        bool isSuccess;

        var param = new CspParameters
                    {
                        KeyContainerName = "SignatureContainer101"
                    };
        using (var rsa = new RSACryptoServiceProvider(param))
            isSuccess = rsa.VerifyData(originalMessage, "SHA256", signedMessage);
        return isSuccess;
    }
}
2
Mormegil On

I am not sure what is the problem, exactly.

How can I make so that if i give the same byte array in both the projects I get the same value returned.

Do you expect SignData to return exactly the same bytes when called twice on an identical message with an identical key? It won’t and it shouldn’t. Every time an “identical” asymmetric (public-key) encryption/signing is done, it should have a different result. That is achieved using a random piece of padding used in the process. It is needed because in public-key cryptography, one of the keys is public, and if no randomness was used, it would make the cryptographic properties weaker. (For more information, see e.g. this answer on Security SE.)

So, you should not compare the result byte-by-byte, you should use the VerifyData method to check whether the signature is correct, not whether it is identical.