0

I haven't done anything similar before and after reading about this I'm still not sure on how to progress.

I have a RSA private key which is protected using a password, stored as text in the local database, and this is my fist problem, how to get the orginal RSA private key.

The second part, relates to signing a document. Basically I have the following method signature which I have to implement:

string GenerateDocumentSignature(string privateKey, string password, string documentId)

So within this methods I will have to reverse the private key and thena apply a RSA encryption.

Can you guys shed some light on how to archive this? Thanks

MeTitus
  • 3,390
  • 2
  • 25
  • 49
  • pls. note that there is a slight difference between signing and encryptin. also, could you provide some more details (some code would be great) – nozzleman Dec 13 '16 at 11:43
  • It's really signing I am talking about and the only code I have if Delphi code which I can't understand anyway. I have a requirement which says I need to sign a document and develop a provider using the method signature above. – MeTitus Dec 13 '16 at 11:55
  • This depends on what format the key is stored in, E.g. if there is an associated password it may be PKCS12/PFX so X509Certificate2 can load that and decrypt it, RSACryptoServiceProvider will accept it as a key and expose a .SignData method. – Alex K. Dec 13 '16 at 11:56
  • @AlexK. I spoke with one of the guys maintaining the Delphi code but he's not sure, the guy who actually implemented this left a good few years ago... Not sure if this makes sense but after getting the private key is "signs" the document using SHA1. Is this how documents are supposed to be sign, using hashs? – MeTitus Dec 13 '16 at 12:10
  • @AlexK. Do I need any certificate? All I've got is the private RSA key and the password. – MeTitus Dec 13 '16 at 12:13
  • Yes, a hash is used - The data is hashed and its the hash that is then signed. – Alex K. Dec 13 '16 at 12:14
  • A certificate is the usual way to store a password protected key. – Alex K. Dec 13 '16 at 12:14
  • Thats the PEM stuff is it? We seem to be storing it on the database, are there any issues associated with it? And given that I don't have any certificate, can I still "unlock" the private key using the X509Certificate2 class? Thanks for your help. – MeTitus Dec 13 '16 at 12:17
  • Yes, if its a PEM file you can use BouncyCastle to load it, E.g. http://stackoverflow.com/questions/243646/how-to-read-a-pem-rsa-private-key-from-net or http://stackoverflow.com/questions/7400500/how-to-get-private-key-from-pem-file - Not sure how you would apply the password. – Alex K. Dec 13 '16 at 12:22
  • Thanks @AlexK. I will read those threads and see if I can find a solution. – MeTitus Dec 13 '16 at 13:28
  • I was able to load the key protected with the password using the BouncyCastle, but I just can't find a way to sign a document. I looked at the links you posted but did not find a way to do it, have you got any other sources which might point me to the right direction? Thanks – MeTitus Dec 13 '16 at 14:45

1 Answers1

1

I was able to get it working using BouncyCastle:

public class SignDocsProvider : ISignDocsProvider
{
    public string GenerateSignature(string privateKey, string password, string documentId)
    {
        var keyPair = ReadPrivateKey(privateKey, password);
        var sha1Digest = new Sha1Digest();
        var rsaDigestSigner = new RsaDigestSigner(sha1Digest);

        rsaDigestSigner.Init(true, keyPair);

        var documentIdToSign = Encoding.ASCII.GetBytes(documentId);

        rsaDigestSigner.BlockUpdate(documentIdToSign, 0, documentIdToSign.Length);

        return Convert.ToBase64String(rsaDigestSigner.GenerateSignature());
    }

    private static AsymmetricKeyParameter ReadPrivateKey(string privateKey, string password)
    {
        AsymmetricCipherKeyPair keyPair;

        using (var reader = new StringReader(privateKey))
            keyPair = (AsymmetricCipherKeyPair)new PemReader(reader, new PasswordFinder(password)).ReadObject();

        return keyPair.Private;
    }
}

internal class PasswordFinder : IPasswordFinder
{
    private readonly string _password;


    public PasswordFinder(string password)
    {
        _password = password;
    }


    public char[] GetPassword()
    {
        return _password.ToCharArray();
    }
}
MeTitus
  • 3,390
  • 2
  • 25
  • 49