Hasan H
Hasan H

Reputation: 141

C# Keyset does not exist when trying to use SignData with RSA

I am new to RSA licensing and I used an online RSA key generator that creates a private and public key. I want to sign some data using these keys and verify the key using the public.

I am using .NET Framework 4.7.2.

These are the functions I tried:

public static string GenerateLicenseFromUserInfo(UserLicense info)  //  To Generate user license
{

//  Temporary license keys I am trying to use
    byte[] privateKeyBytes = Convert.FromBase64String("MIICXAIBAAKBgQC8IG4CySTEOZhmDwlTdR4Yd6xoqoJGsfze/RvrZgY72HAuWK0Y3DKrNdFiM+Z2O1weArCyoTbGsZ7UcxhCFKQLSsHooZveQTTHDHvm7cIts8jEMDw/xbPDrMQH/vYjRshNo8vOsVwxQELVzvrMA7+A/3ITKvbL0PTSDxxMcHRQDwIDAQABAoGAUNNqEH5U8o2AQZECQ74U0RRRmaJwWGlOKIv8e9WYpgumnvLwY7bvegmkTRnZUUDNogMr4YNMIm/bupE8gd+WXpo8TrHoFDNYFGB07eAnDR/ZNcSboBLGw9JKnRCD8kZ2QYwmH/wKdJL2VppC+ooVit2AcDWeCh9pPl8gF5R054kCQQDwxfnogy19yEF6eXEBQD4um/nDUbjRaudyc/i16H6SBw1+q/sQhX/QArgDwxnU5vfUWRZ4BQGw6IlQWYNzbxuzAkEAyAYgCRIWu+lWbJEErLg4gGq4D7+B3kP7SP3+QU6SBL/eVwqtgSiWUEjB84jlu73u9eqcsDJMfVF3WxnAaOQcNQJAY7vuQBUOY/ruvJfPapA88bukYvbYEs8wniVR0bBDtaN8QItmzTovbm+h39USPzGJWQmqF/8i6y/3qTPbEpbkpwJAWzrH87snWU+EloHSEwD27ENAbhZXokt5WgJWq+ytFrN4MlTxa75aSIXWyD/BIE7xpYH7MzXNwz6b5JYrNuwLnQJBAIChHs1sxLfp0HPKnPtMEJDmYlRmM176HKywg7q77yyij2K/90ijjgSG8YrXkeLrDBieCbMdxuruevZ+yBQPhr4=");
    byte[] publicKeyBytes = Convert.FromBase64String("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8IG4CySTEOZhmDwlTdR4Yd6xoqoJGsfze/RvrZgY72HAuWK0Y3DKrNdFiM+Z2O1weArCyoTbGsZ7UcxhCFKQLSsHooZveQTTHDHvm7cIts8jEMDw/xbPDrMQH/vYjRshNo8vOsVwxQELVzvrMA7+A/3ITKvbL0PTSDxxMcHRQDwIDAQAB");


    // Create an RSA object with the public and private keys
    var rsa = new RSACryptoServiceProvider();
    rsa.ImportParameters(new RSAParameters
    {
        Modulus = publicKeyBytes,
        Exponent = new byte[] { 1, 0, 1 },
        D = privateKeyBytes
    });

    string userInfo = info.ToString();

    byte[] userInfoBytes = Encoding.UTF8.GetBytes(userInfo);

    // Sign the user information using the private key
    byte[] signature = rsa.SignData(userInfoBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);  //  Exception thrown here : Keyset does not exist

    // Convert the signature to a string for distribution to the user as the license key
    return Convert.ToBase64String(signature);
}


public static bool VerifyLicenseFromUserInfo(string receivedLicenseKey, UserLicense info)  //  To Verify license is for this user
{

    byte[] publicKeyBytes = Convert.FromBase64String("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8IG4CySTEOZhmDwlTdR4Yd6xoqoJGsfze/RvrZgY72HAuWK0Y3DKrNdFiM+Z2O1weArCyoTbGsZ7UcxhCFKQLSsHooZveQTTHDHvm7cIts8jEMDw/xbPDrMQH/vYjRshNo8vOsVwxQELVzvrMA7+A/3ITKvbL0PTSDxxMcHRQDwIDAQAB");

    // Convert the public key from bytes to an RSA object
    var rsa = new RSACryptoServiceProvider();
    rsa.ImportParameters(new RSAParameters
    {
        Modulus = publicKeyBytes,
        Exponent = new byte[] { 1, 0, 1 }
    });

    string userInfo = info.ToString();

    byte[] userInfoBytes = Encoding.UTF8.GetBytes(userInfo);


    // Convert the license key back to a byte array
    byte[] receivedSignature = Convert.FromBase64String(receivedLicenseKey);

    // Verify the license key using the public key
    return rsa.VerifyData(userInfoBytes, receivedSignature, HashAlgorithmName.SHA256,RSASignaturePadding.Pkcs1);
}

When I run the program, when using the GenerateLicenseFromUserInfo function, I get the following:

System.Security.Cryptography.CryptographicException: 'Keyset does not exist'

in the SignData function in GenerateLicenseFromUserInfo

I think my problem is converting my private and public keys to RSAParameters but I couldn't find a way to do it.

Upvotes: 0

Views: 477

Answers (1)

MikeZ
MikeZ

Reputation: 1355

Maybe this will help. I just ran into a similar problem. I have a CspBlob with private & public keys exported from legacy NT C++ code with CryptExportKey. I can successfully .ImportCspBlob the CspBlob into a new RSACryptoServiceProvider and everything looks good at first glance but when I try to .SignData I get the "Keyset does not exist" exception. I noticed that CspKeyContainerInfo.KeyNumber was 1 (Exchange) and setting it to 2 (Signature) with CspParameters now allows me to .SignData with the private key.

Upvotes: 1

Related Questions