3

We have a signing service that accepts a sha256 hash as an input and signs the hash using pkcs11 and bouncy castle libraries in C# encode the signed digest to Bae64 and sends it to the requester. So, essentially we are generating a hash of a hash and signing the hash.

The requester on the other end in order to verify this decodes the base64 received digest and verifies it. I have used a .NET library at my end in PowerShell and implemented a verification process that verifies. please see below.

## Load a certificate Public key and verify

$certusedforsigning = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2

$certusedforsigning.Import($signingcertificate)

$certusedforsigning.PublicKey.key  -as [System.Security.Cryptography.RSACryptoServiceProvider] | Out-null

$oid = [System.Security.Cryptography.CryptoConfig]::MapNameToOID('SHA256')

$padding = [System.Security.Cryptography.RSASignaturePadding]::Pkcs1

$result = $certusedforsigning.PublicKey.key.Verifyhash($originalhashinBinary,$signedbinary,'SHA256',$padding)

$result

if($result -eq 'True' ) { write-host 'Signature verified True'} else { write-host 'Signature validation Failed'}

}
}

Now, in order to get around hashing the hash, we are encrypting the received sha256 hash using the RSA private key. Now I presume I need to use the public key to decrypt the hash, generate a sha256 hash of the original message and compare the two in order to verify.

Is there a method or function that is available in .NET that will let me do this? Can I accomplish this Using OpenSSL ? could you please point me how to accomplish verifying such a message as described above. thanks.

Keyur Ramoliya
  • 1,900
  • 2
  • 16
  • 17
Teja
  • 43
  • 2
  • 9

1 Answers1

1

Generally encrypting with a private key is not well defined. There are two PKCS#1 v1.5 padding methods: one for signing (with a private key) and one for encryption (with a public key). So it depends on the implementation which padding method is used.

Let's assume that the one for signing is used. Checking this is easy: just regenerate a signature over the same data. If it is identical to a previous one then the padding for signing is selected (with the PKCS#11 implementation choosing by the type of key).

To verify the signature you would simply have to hash the data, then perform the signature validation (which in C# can include the hashing) and verify against the base 64 decoded signature value. No specific magic is required other than this.

If the non-deterministic encryption scheme is used then you may want to reconsider your protocol. RSA padding is central to the security provided by the RSA cryptosystem.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
  • Hi Maarten, thanks for the update...the crypto service provider class in .net api won't let me decrypt an encrypted message and the pkcs1 padding. As expected, when you try to verify a message encrypted using the public key, the verification fails. – Teja Jul 02 '18 at 13:47
  • Then the wrong padding may have been used. You could try and decrypt the signature using *raw* RSA, so you can have a look and compare to PKCS#1 (there is an RFC 3447 that defines RSA including the padding methods). I think you meant *encrypted using the private key and verified with the public key, right? – Maarten Bodewes Jul 02 '18 at 14:23
  • Hi Maarten, 'Raw RSA', will do a bit of research to find out which library supports that, be glad if you can point me to something. Yes, It was a typo, I meant encrypt using the private key and verify using public. However, found out from your comment and others that pkcs1 padding mode is different to signature vs encryption, hence the encrypted digest differs. you can only encrypt a message which is the RSAkeysize-11bytes, which is the padding size. – Teja Jul 03 '18 at 09:01