Search code examples
c#androidcryptographyrsasign

Sign string with SHA1RSA and existing rsa private key c#


i have a rsa private key and i wanted to sign the data with it. i wrote this code but it doesn't work:

public string Sign(string text)
{
    var sha = new SHA1Managed();
    var encoding = new UTF8Encoding();
    var bytes = encoding.GetBytes(text);
    var digest = sha.ComputeHash(bytes);

    var cert = new X509Certificate2(Convert.FromBase64String(PermissionKey));
    var rsa = (RSACryptoServiceProvider)cert.PrivateKey;
    var rsaFormatter = new RSAPKCS1SignatureFormatter(rsa);
    rsaFormatter.SetHashAlgorithm("SHA1");

    var SignedHashValue = rsa.SignData(digest, sha);
    return Convert.ToBase64String(SignedHashValue).Replace("=", "") + "\n";
}

i get this exception:

'Cannot find the requested object. 

when i tried to create X509Certificate2:

var cert = new X509Certificate2(Convert.FromBase64String(PermissionKey));

PS: I'm tiring to simulate the android code in c#. here is the main android:

public static PrivateKey makePrivateKeyFromPermissionKey(String permissionKey)
        throws InvalidKeySpecException, NoSuchProviderException, NoSuchAlgorithmException {
    KeyFactory keyFactory;
    byte[] certificate = decode(
            permissionKey
                    .replaceAll("\\n", "")
                    .replace("-----BEGIN RSA PRIVATE KEY-----", "")
                    .replace("-----END RSA PRIVATE KEY-----", "")
    );
    if (Build.VERSION.SDK_INT < 27) {
        keyFactory = KeyFactory.getInstance("RSA", "BC");
    } else {
        keyFactory = KeyFactory.getInstance("RSA");
    }
    return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(certificate));
}

Solution

  • I found the answer. i used CSharp_easy_RSA_PEM library in order to read the private key.

    public static string Sign(string text)
    {
        var privateRSAkey = Crypto.DecodeRsaPrivateKey(PermissionKey);
        var rsa = privateRSAkey;
    
        var hasher = new SHA1CryptoServiceProvider();
        var e = new UTF8Encoding(true);
        var bytesFirmados = rsa.SignData(e.GetBytes(text), hasher);
    
        return Convert.ToBase64String(bytesFirmados);
    }