I am trying to sign a string with a PKCS#8 key using SHA-256 with RSA.
The RSACng.SignData()
method requires a RSASignaturePadding, of which the options are Pkcs1
and Pss
. I can't find anything definitive to tell me which would be used for PKCS#8.
// Decode Token (token is Base64 & PKCS8 encoded)
byte[] decodedKey = Convert.FromBase64String(myBase64String);
CngKey key = CngKey.Import(decodedKey, CngKeyBlobFormat.Pkcs8PrivateBlob);
// Build signature
string signature = "123abc";
byte[] bytes = Encoding.UTF8.GetBytes(signature);
// Sign signature using key & SHA256 w RSA
var unsigned = new RSACng(key);
byte[] data = unsigned.SignData(bytes, HashAlgorithmName.SHA256, <??????>);
Cryptography is all new to me, so if my approach is way off, please let me know.
PKCS#8 describes a way to encode / decode private keys. If this key is an RSA key then that key can indeed be used to generate RSA signatures.
The padding doesn't require any specific key properties. It just requires the size of the key as input which - for RSA - is identical to the modulus size (as unsigned number, in bits).
The modular exponentiation that follows is always the same for RSA signature generation. It raises the padded hash value to the private exponent. So you can choose which padding you want to use for your specific protocol.
If you don't want to specify a protocol you could take a look at CMS (Cryptographic Message Syntax) - previously known as PKCS#7.
In case of RSA with PKCS#1 v1.5 padding the padding is deterministic, which makes the whole RSA signature generation deterministic. In case of PSS it is a non-deterministic operation, i.e. a random number generator is involved. The newer PSS has a better security proof than PKCS#1 v1.5, but PKCS#1.5 has not been broken.