Which privatekey format is this? - format

I've a private key made with OpenSSL and encrypted with RSA like this:
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQILJ8rNTk54VICAggA
MBQGCCqGSIb3DQMHBAiXuThuf12hMwSCBMhrm8H2j7yzLBOIvSWbLoyUmIn7e9zA
6PLDzj1dos+h+wAkPN0IgJlkdoBBXlnF7tzGdoctOYOKiu/p+HLzMnvHaDfNSFwz
5zx4yyZsKtf90gT6IVuJy7TMiLK3gk4gdZJc820OeRr1FjdRV3iVpTXbVfpwG/B3
IbV0PX3ZaHeR1m8vWI0/XQB7ZL7lLT+3MO66X/PAMTPA9joFMxuPFasIb2uXSqe/
CJNOyY4iW89uYHFiOe53e4ggUdT/rupoR4OSNKKEH5f1y+FIuH1xNvlmi14hJn+k
KOOi89vVIcvh4abCM+jhYwpPOGB8Sz2bAXsYocgZPvKtKakHlis7RcSsd5Usx9Nt
tgQ=
-----END ENCRYPTED PRIVATE KEY-----
And I've stored it into a user.key file.
Actually I'm implementing a CMS encrypt and decrypt project in objective-c. Now I'm trying to decrypt my encrypted container file using certificates, private key, and so on...
I'm a little bit confused which method from OpenSSL I should choose to load the aforementioned key into an EVP_PKEY object.
It suggests me the following formats:
FORMAT_ASN1
FORMAT_PEM
FORMAT_PKCS12
FORMAT_MSBLOB
FORMAT_PVK
I know that it's not PEM and PKCS12. I would guess ASN1 or PVK but I really don't know and I haven't found any further information on this in the OpenSSL docu.
Can anyone tell me please which format the aforementioned key has?
EDIT:
To specify my question a bit more: I have the aforementioned key loaded into a BIO. I can read this BIO with BIO_read(keybio, ...) successfully and it contains the key (in ascii). Now I want to get an EVP_PKEY from this BIO.
I've tried...
EVP_PKEY *key = PEM_read_bio_PrivateKey(keybio, NULL, 0, NULL);
... but this doesn't work. When I call this it asks me to enter the passphrase in the console and when I do this, the key is NULL. :-/

The key is a PKCS#8 EncryptedPrivateKeyInfo wrapped in a PEM-container.
You can do something like this to get it into an EVP_PKEY-object:
// This must be called once:
OpenSSL_add_all_algorithms();
BIO* bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
X509_SIG* p8 = PEM_read_bio_PKCS8(in, NULL, NULL, NULL);
if(p8==NULL){
BIO_printf(bio_err, "Error decoding key\n");
ERR_print_errors(bio_err);
return;
}
PKCS8_PRIV_KEY_INFO* p8inf = PKCS8_decrypt(p8, password, strlen(password));
if(p8inf==NULL){
BIO_printf(bio_err, "Error decrypting key\n");
ERR_print_errors(bio_err);
return;
}
EVP_PKEY* pkey = EVP_PKCS82PKEY(p8inf);
if(pkey==NULL){
BIO_printf(bio_err, "Error converting key\n");
ERR_print_errors(bio_err);
return;
}

That (extended) PEM format is used by OpenSSL for PKCS#8 encoded private keys.

Related

Not able to export ECDSA certificate from Windows Store

PFXExportCertStoreEx fails when I try to export ECDSA certificate from Windows Store.
I need to get both the public key and private key of the certificate.
Is the API usage wrong for ECDSA certificate?
I am able to export cert and key for a RSA certificate from Windows Store.
Thanks in advance.
Edit - Psuedo code will be as below:
-CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_MAXIMUM_ALLOWED_FLAG, L"MY"); // Open certificate store
-CertEnumCertificatesInStore() // Get certificate context
-hStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, 0) // Open a memory store
-CertAddCertificateContextToStore // Add certificate context to memory store
-PFXExportCertStoreEx(hStore, &blob, "export_password", NULL, EXPORT_PRIVATE_KEYS | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY) // Try to get certificate blob

Verify signed data vault offline

I'm sending to a client a public_key and a payload plus a signature.
I'm trying to verify the signature on the client using the public_key and payload but I can't find a way to get the data verified. Every time I receive false as a response regardless of what I'm doing.
I'm using vault to sign the payload
def sign(box_identifier, data) do
Vaultex.Client.write("transit/sign/#{box_identifier}",
%{
input: data,
hash_algorithm: "sha2-256"
},
#authentication_strategy,
{#token})
end
Vault.Transit.sign("coucou", Base.encode64("test"))
_____________________________________________________________
digest = OpenSSL::Digest::SHA256.new
key = OpenSSL::PKey::RSA.new File.read 'key.pem'
key.public_key.verify digest, signature, "test"
-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAzj0qLxEc0Qu9g9nxdMRe
jBaUD0+GuQITiAPEDOrjScJTznJrR9hXqO14BqepuEmcz4irv4hEkBEBfqZ1XnP9
2fc9zG4A20lepqDRwPhkEdI4D71KRPSxv/a+O2HrAhTYH17NbsYDtpkFCdepC6FC
01aso679d3kAZiZ+GD2OLDWifreBVPE2aXacJYXZZ4kTkchsevY3PnAcOG4LmM6b
kUoF1qfP6tJ/VItJXyqSC2PI9Io28zFhwOf6cPLEQCBCTNCNwHunqHW8olcE/Xfn
b2toym0/UvW3kH/P4h+TE1ZoCV5FWwcx9hcAy1TC0zm4D5Xwt0/4Pgj1GiXFGOY4
WKGyuDK8gs7QsSDqu+B5p0xiDg7226bpplVxR/P87CohYTtYZj/lO03G2ZEj3pCr
/juxThdzTgO5xUcPV5GFbPjlK1TIIb5XVZZzW6+sviB6cYZ5T/Xp9dtbR8G9Zt9n
gLlaKU7U/DDQxRv2uiCZy5U/DUpfxY56r4Y73Ir2YgmZY1PKLC2a5/w3wScVZILN
fnxnVYOzSPPaKxAJWbZsZjxXJS0veE8RgGFHgWfe8+qPCEnx81Jf2NzupQHO1KIk
UnlYGcPESk/90psDNsmISSdtF2D6j4k28k0ncViTu2eMKBX81W8TgTeHtQa3zR0S
upN2o25b3Wi2oQU14kTdOCcCAwEAAQ==
-----END PUBLIC KEY-----
Am I even capable of validating the signature offline when its signed by vault ?
Yes, it's possible to verify the signature offline. My answer is going to mention some Ruby specifics, since I didn't notice this was Elixir until after I started researching a bit more.
By default, when signing with a RSA key, Vault uses the PSS algorithm for the signature. The verify method on OpenSSL::PKey::PKey is expecting PKCS #1 v1.5. Here's some useful info about the pros and cons of the two.
In addition to this algorithm difference, you need to strip off the vault:v1: from the returned signature from Vault.
Here's some sample Ruby code to sign and then verify the signature:
transit_key = "test_key"
message = "test"
# Returns something like:
# vault:v1:B3reNpf8e/WyAYzBzyWz3oSUM...
signature = Vault.logical.write(
"transit/sign/#{transit_key}/sha2-256",
input: Base64.encode64(message),
signature_algorithm: "pkcs1v15"
).data[:signature]
signature = signature.split(":")[2]
# Gives us the PEM encoded public key
# -----BEGIN PUBLIC KEY-----
# ...
public_key = Vault.logical.read("transit/keys/#{transit_key}").data[:keys][:"1"][:public_key]
public_key = OpenSSL::PKey::RSA.new(public_key)
digest = OpenSSL::Digest::SHA256.new
puts public_key.verify(digest, Base64.decode64(signature), message) # returns true
puts public_key.verify(digest, Base64.decode64(signature), message + "modified") # returns false
Looks like as of Ruby 2.5, there's a new verify_pss method on the OpenSSL::PKey::RSA class.
signature = Vault.logical.write(
"transit/sign/#{transit_key}/sha2-256",
input: Base64.encode64(message),
signature_algorithm: "pss"
).data[:signature].split(":")[2]
puts public_key.verify_pss(digest, Base64.decode64(signature), message, salt_length: :auto, mgf1_hash: "SHA256") # returns true
puts public_key.verify_pss(digest, Base64.decode64(signature), message + "modified", salt_length: :auto, mgf1_hash: "SHA256") # returns false

DEX LDAP connector token signing

I am playing around with DEX and openldap. When I get a token back in my browser and put it into JWT debugger with the public key i generated, it doesn't verify the signature. I am trying to step through the code of DEX, but the debugging tools are not really working on my computer. I have resorted to log statements. I can't really find where I can observe the signing of the token to see if the program is using the keys i provided or not. Which function actually signs the token and how can I observe what key it uses to sign?
The key can be read from the DEX "keys" endpoint which can be obtained from:
http://your.dex.com/.well-known/openid-configuration
Typically, it would be something like:
http://your.dex.co/keys
After that, the public keys can be extracted using the following program:
https://play.golang.org/p/wVusucNGDI
One of those keys will be able to validate the token:
from jose import jwt
key = '''-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArT9AtIlC8MxhLYhz8ODH
...
+QIDAQAB
-----END PUBLIC KEY-----'''
encoded = 'eyJh...ocw'
audience = ''
if audience == "":
opts = {"verify_aud": False}
else:
opts = {}
opts['verify_at_hash'] = False
decoded = jwt.decode(encoded, key, audience=audience, options=opts)
print(decoded)

Decrypt PKCS7 in Ruby on Rails

I try to decrypt PKCS7 data, but always receive error OpenSSL::PKCS7::PKCS7Error - wrong content type on method "pkcs7.decrypt(key, cer)".
example:
cer = OpenSSL::X509::Certificate.new(File.read("path/cert.cer"))
key = OpenSSL::PKey::RSA.new(File.read("path/private.key"), "111111")
crypted_data = File.read('path/pkcs7') # contains xml-file and signature "-----BEGIN PKCS7----- ... -----END PKCS7-----"
pkcs7 = OpenSSL::PKCS7.new(crypted_data)
decrypted_data = pkcs7.decrypt(key, cer) # error is here
need help! how to get data from the encrypted string?
updated:
on bash I can solve this task by following code:
openssl smime -verify -noverify -inform PEM -nointern -certfile "path/cert.cer" -CAfile "path/cert.cer" < path/pkcs7
returns xml file.
Solution founded!!!
cert_store = OpenSSL::X509::Store.new
my_cert = OpenSSL::X509::Certificate.new(File.read("remote.cer"))
signature = OpenSSL::PKCS7.new(File.read('pkcs7-resp.file'))
signature.verify([my_cert], cert_store, nil, OpenSSL::PKCS7::NOVERIFY)
signature.data

Installing a java card applet fails due to RSA keypair generation

I'm trying to install an applet into a J3A040 JCOP card.
As install method I have the following:
protected MainApplet() {
try {
// CREATE RSA KEYS AND PAIR
m_keyPair = new KeyPair(KeyPair.ALG_RSA_CRT, KeyBuilder.LENGTH_RSA_2048);
// STARTS ON-CARD KEY GENERATION PROCESS
m_keyPair.genKeyPair();
// OBTAIN KEY REFERENCES
m_publicKey = (RSAPublicKey) m_keyPair.getPublic();
m_privateKey = (RSAPrivateKey) m_keyPair.getPrivate();
} catch (CryptoException c) {
//this line will give you the reason of problem
short reason = c.getReason();
ISOException.throwIt(reason); // for check
}
register();
}
The installation always fails with the following error:
pro.javacard.gp.GPException: Install for Install and make selectable failed SW: 6A80
at pro.javacard.gp.GlobalPlatform.check(GlobalPlatform.java:1092)
at pro.javacard.gp.GlobalPlatform.installAndMakeSelectable(GlobalPlatform.java:798)
at pro.javacard.gp.GPTool.main(GPTool.java:478)
However, if I remove the keypair generation, everything works fine.
I have read the card specifications and it stands:
. RSA and RSA CRT (1280 up to 2048 bits keys) for en-/decryption and
signature generation and verification1 d. RSA CRT key generation (1280
up to 2048 bits keys) in a secured environment
I guess it shouldn't be a problem.
Any guesses?
The problem is caused by an invalid cast: you asked for an RSA KeyPair with the private key in the Chinese Reminder Theorem format (ALG_RSA_CRT).
That is why the getPrivate() method does not return an RsaPrivateKey instance, but an RsaPrivateCrtKey instance. Casting to RsaPrivateKey causes the 6A80 status word.
So you should either use the standard algorithm:
m_keyPair = new KeyPair(KeyPair.ALG_RSA, KeyBuilder.LENGTH_RSA_2048);
, or use a correct cast:
m_publicKey = (RSAPublicKey) m_keyPair.getPublic();
m_privateKey = (RSAPrivateCrtKey) m_keyPair.getPrivate();

Resources