java.security.InvalidKeyException: Private keys must be instance of RSAPrivate(Crt)Key or have PKCS#8 encoding - rsa

I have created a sample web service to digitally sign a document using etoken. It is creating the Signature file for the first time.But when I am trying to run the web service again it throwing me the following error.Can anyone update regarding this?
java.security.InvalidKeyException: Private keys must be instance of
RSAPrivate(Crt)Key or have PKCS#8 encoding at
sun.security.rsa.RSAKeyFactory.translatePrivateKey(RSAKeyFactory.java:288)
at
sun.security.rsa.RSAKeyFactory.engineTranslateKey(RSAKeyFactory.java:191)
at sun.security.rsa.RSAKeyFactory.toRSAKey(RSAKeyFactory.java:111)
at
sun.security.rsa.RSASignature.engineInitSign(RSASignature.java:106)
at sun.security.rsa.RSASignature.engineInitSign(RSASignature.java:99)
at java.security.Signature$Delegate.init(Signature.java:1152)

Related

Azure KeyVault signature fails during verification using javascript libraries intermittently

I am using Azure key vault for creating and storing my Secp256k1 keys. I am also using the sign API for getting my input string signed. I am working on a Secp256K1 blockchain network.These are steps I follow to get the signature in Golang.
Converting my Hex string into Byte[]
Sha256 of this Byte[]
RawURL encoding of this Sha.
b64.RawURLEncoding.EncodeToString(sha)
Sending this to Key vault for signature.
Decoding the response using RawURLEncoding.
b64.RawURLEncoding.DecodeString(*keyOpsResp.Result)
Doing Hex of the []Byte array returned from 5th Step.
Sending the signature to the blockchain.
The problem I am facing is that signature is invalid sometimes. As in 2/5 times it works and other times signature verification fails.
I am thinking there is some special chars or padding thing that I am missing.
How can I resolve this?
PS: Azure uses non-deterministic signatures where as chains usually use deterministic signs. I did some reading and found out that for verification it does not matter both could be verified successfully. Let me know if I am wrong.
• Since you are using base64 encode RawURL for encoding purposes, you can check whether the following parts are included in the token request for the keyvault signature validation. They are as follows: -
aud (audience): The resource of the token. Notice that this is https://vault.azure.net. This token will NOT work for any resource that does not explicitly match this value, such as graph.
iat (issued at): The number of ticks since the start of the epoch when the token was issued.
nbf (not before): The number of ticks since the start of the epoch when this token becomes valid.
exp (expiration): The number of ticks since the start of the epoch when this token expires.
appid (application ID): The GUID for the application ID making this request.
tid (tenant ID): The GUID for the tenant ID of the principal making this request. It is important that all the values be properly identified in the token for the request to work
• Also, please check the size of the block that is dependent on the target key and the algorithm to be used for validation of signature. In that, please check the ‘decryptParameters’, ‘algorithm’ and ‘ciphertext’ parameter for the returns that are displayed after the decrypt operation during signature validation.
Please find the below links for more details: -
https://learn.microsoft.com/en-us/java/api/com.azure.security.keyvault.keys.cryptography.cryptographyasyncclient.decrypt?view=azure-java-stable

How can I add a private key to a certificate in the windows trust store in c++?

I have a file with a certificate in it, and I have a file with a private key file in it.
if I run this command
certutil –MergePFX certfile.cer certfile.pfx
I get a pfx file that if I run with explorer, it runs the windows certificate import wizard. If I run through the wizard, I end up with the cert with the key in the windows trust store. Exactly what I need.
I'm trying to do this programatically.
The problem seems to be in the CertAddCertificateContextToStore function.
In the remarks it says:
The certificate context is not duplicated using CertDuplicateCertificateContext. Instead, the function creates a new copy of the context and adds it to the store. In addition to the encoded certificate, CertDuplicateCertificateContext also copies the context's properties, with the exception of the CERT_KEY_PROV_HANDLE_PROP_ID and CERT_KEY_CONTEXT_PROP_ID properties.
So certduplicatecertificatecontext very specifically will not copy the private key, and it seems that CertAddCertificateContextToStore doesn't either.
I have a HCRYPTPROV struct with my private key and I use CERT_KEY_CONTEXT_PROP_ID and CERT_KEY_PROV_HANDLE_PROP_ID (I tried them both) to CertSetCertificateContextProperty my certificate context, and then I store it in the windows trust store with CertAddCertificateContextToStore. And no matter what I try, the certificate goes in without the private key.
I'm verifying this with the certmgr tool that shows if a private key is attached, and I can also see it not work when I use that client certificate in a curl request I'm making.
Another thing I tried was this:
The last parameter to CertAddCertificateContextToStore is the handle to the copy of the context that is made. I figure the original context is the one I created where I read the certificate in from disk. This new certificate is the one tied to the actual on-disk store that certmgr reads.
So after I call CertAddCertificateContextToStore, I take the new cert and I add the private key, again via CertSetCertificateContextProperty, and then for good measure, I call CertControlStore to push the in-memory version of the context to disk. Still no effect. Every function call succeeds, but the private key never makes it to the windows trust store.
So in short, my question is what is the windows certificate import tool doing that I am not that will allow me to store a private key along with the certificate in the windows trust store?
I've found a handful of other questions and program examples and message boards dating back to 2002 and none are very explicit, and none of the code examples do exactly what I need, but I know I have all the pieces, they just don't yield the result.
I strongly believe that you set incorrect properties. You should set only CERT_KEY_PROV_INFO_PROP_ID context property in the CertSetCertificateContextProperty call to associate certificate with private key.
If you have a HCRYPTPROV handle, then you have all necessary information to construct CRYPT_KEY_PROV_INFO structure.

What is the format for sending curve parameters and the public key using ECDHE key exchange?

I attempting to use ECDHE key exchange with AES encryption using mbedtls library on client side.The keys are successfully being generated using the
following program .
Is there any standard format to attach the curve parameters and public key to the encrypted file so that the server(may use library other than mbedtls) can parse those?
RFC4492 defines the supported elliptic curves extensions. This extension is sent as part of the Client Hello message.
The server will send the used curve in its ServerKeyExchange message.
The public keys are sent using the ServerKeyExchange and ClientKeyExchange messages.

IDP Initialized SSO, how to configure when dont have the pwd for PrivateKey

I am using spring-security saml extension to implement the IDP initiated SSO for my application. I am using https protocol and signature/encryption is ON. I dont need SLO/SP-Initiated SSO.
On the transport layer's encryption/decryption (because using HTTPS protocol), I am fine as My web container (SP one) is going to take care of the decryption part. And this certificate could be different then SP's certifiate.
At the SP end, I need the IDP's public key to verify the signature on SAMLAuthResponse Msg, which I have as part of the IDP's metadata file...so no issues here.
Couple of qns:
For decryption of the SAMLAuthResponse Msg, Do I need SP's
certificate's private key?
And If I need the private key, how to
create the bean definition for keyManager when I have the jks file,
jks-pwd, alias, but no pwd for privatekey? Can I pass the empty string (as "") in the password field in the alias-password value pair.
You can skip usage of private key in this case. You can find detail on how to use Spring SAML without keystore in the manual chapter 8.1:
In case your application doesn't need to create digital signatures
and/or decrypt incoming messages, it is possible to use an empty
implementation of the keystore which doesn't require any JKS file -
org.springframework.security.saml.key.EmptyKeyManager. This can be the
case for example when using only IDP-Initialized single sign-on.
Please note that when using the EmptyKeyManager some of Spring SAML
features will be unavailable. This includes at least SP-initialized
Single Sign-on, Single Logout, usage of additional keys in
ExtendedMetadata and verification of metadata signatures. Use the
following bean in order to initialize the EmptyKeyManager:
<bean id="keyManager" class="org.springframework.security.saml.key.EmptyKeyManager"/>

SignedCms.CheckSignature() with renewed cert -> new serial?

i am using
SignedCms.CheckSignature(certColl, true)
(with only one cert in certColl) to verify the signature of a pkcs-7 message. My problem is that i dont want to change the (public part of the) signers certificate on my server after the signer has renewed his certificate :-( The public key, issuer and subject are remaining unchanged after signer has renewed his certificate! So this has to work - at least in my opinion, even if i´m not a crypto-geek :-)
..but, unfortunately the .NET-Framework throws a Cryptographic Exception "Cannot find the original signer" like the stacktrace says exactly at:
SignerInfo.CheckSignature(X509Certificate2Collection extraStore, Boolean verifySignatureOnly)
This must be because the serial number of the signers certificate has changed and the SignerIdentifier property is readonly and set to IssuerAndSerialNumber.
Does anyone know how workaround this?
Or do i have to implement a "handmade" signature verifying with sth like: signedMessage.ComputeSignature(signer, false)?
Thanks in advance and happy programming,
Krile
For all interested on this issue:
Someone told me that this is due to the PKCS #7 specification, which states that the SubjectKeyIdentifier is always set to IssuerAndSerialNumber.