What to do when Azure Key Vault rejects certificate and says: Unsupported key operation(s): "wrapKey", "unwrapKey" - azure-keyvault

I am trying to generate X509 certificates in C# code (using the X509Certificate2 class) and upload them to an Azure Key Vault.
I have found out that if my certificate contains the flag X509KeyUsageFlags.KeyEncipherment, the vault will reject the certificate with this error message:
Unsupported key operation(s): "wrapKey", "unwrapKey". Supported values are "sign", "verify".
Does anyone know what to do about this? Of course I can remove that flag from my generated certificates, but I want to understand why Azure rejects it. Is it possible at all to upload certificates to an Azure Key Vault when they contain this flag?
I ahae read this documentation page, but it did not tell me much: https://learn.microsoft.com/en-us/azure/key-vault/keys/about-keys-details
(This is a more specific follow-up to my earlier question here.)

• You are encountering this issue because the key along with this x509 .pem certificate is not in correct format and not combined with the certificate. That is, the certificate type that you are importing should not have its information contained in it in base64-encoded byte form. It should be in its raw form.
Thus, the error signifies that the certificate key you are trying to import is to be used to sign and verify the application content and the application using this certificate will hash the data locally using the certificate’s keys. Thus, the certificate key should not itself be in other unacceptable form. Also, the key generation algorithm may not be supported as stated from the error that you are encountering.
• Hence, if you are importing a certificate in PEM(whether that be X509 certificate) format, then "contentType" should be "application/x-pem-file" type. The value parameter will just be the raw text contents of your PEM file and need not to be in base64-encoded-byte, because PEM certificate is already in a text format, so base64-encoding is not required. Thus, the private key of the certificate should be in the same format as the certificate contents encryption algorithm. It need not be masked or converted in another format and it should be combined with the certificate itself.
Please refer to the links below for more information: -
https://learn.microsoft.com/en-us/azure/key-vault/certificates/certificate-scenarios#formats-of-import-we-support
https://learn.microsoft.com/en-us/answers/questions/258583/import-certificate-api-for-azure-key-vault.html

Related

Is it possible to refer to a certificate in Azure Key Vault via a file name?

In the scenario for this question I am using a library that takes a certificate path as a parameter.
Does that mean that it is not possible for me to store my certificate in Key Vault?
Does that mean that it is not possible for me to store my certificate in Key Vault?
It is possible, but you have to give it a Name (key) to access it.
When you add/import x.509 certificates to Azure Key Vault Certificates, you give it a name (which acts as a unique key for that certificate), and you access that certificate by that name.
More info here: https://blogs.technet.microsoft.com/kv/2016/09/26/get-started-with-azure-key-vault-certificates/
Now, with regards to your other question, I am assuming you are wondering how to access a certificate from an Azure function. In your other question, you have this:
ApiSettings["SigningCertPath"]
And you indicated, you are using a (3rd party) library which picks the signing certificate path, and presumably loads that certificate. I do not know how your (3rd party) library works, or if it even works with Azure Key Vault. But it appears your library is loading the cert from a file. You did not mention if you still would like to do it that way.
But as alternative, you can load/import your certificate into your Function App (Platform features > SSL). Besides taht, you also need to add this entry to the Application Settings (on Azure portal): key WEBSITE_LOAD_CERTIFICATES and the value of *. This loads all certificates in your SSL bindings and into your Function App's certificate store. Then your function can read/get the certificate as you would get it from a local certificate store.
You can do the above instead of storing your certs in Key Vault. But you can also have all your other certs in Key Vault and only store the client certificate you need to access Key Vault from within your function.

What is the file with .p8 extension? (APNs Auth Key / JWT)

I think it is a little ridiculous but it's hard to find information about what is this file. I've found a lot info how to get this Apple Push Notification Authentication Key, but i also want to know exactly what is it.
Here is some info i have found:
Benefits:
No need to re-generate the push certificate every year;
One auth key
can be used for all your apps;
Same for sandbox and Production.
From Apple Docs:
Token-based provider connection trust: A provider using the
HTTP/2-based API can use JSON web tokens (JWT) to provide validation
credentials for connection with APNs. In this scheme, you provision a
public key to be retained by Apple, and a private key which you retain
and protect. Your providers then use your private key to generate and
sign JWT provider authentication tokens. Each of your push
notification requests must include a provider authentication token.
You can use a single, token-based connection between a provider and
APNs can to send push notification requests to all the apps whose
bundle IDs are listed in your online developer account.
Every push notification request results in an HTTP/2 response from
APNs, returning details on success or failure to your provider.
Further check Token-Based Provider-to-APNs Trust section.
Questions:
What is actually the .p8 file?
What programm can open it? (Keychain didn't work for me)
Is there a way to convert it to .pem or .p12?
A little flow-out question in order to not create a new topic: Does the server side operate with .p8 the same way as .p12 or it should be additional tools added?
The following is the state of my research:
The APNS .p8 file contains the PRIVATE KEY that is used to SIGN the JWT content for APNS messages.
The file itself is a pure text file, the KEY inside is formatted in PEM format.
The part between the -----BEGIN PRIVATE KEY----- and -----END PRIVATE KEY----- is a base64 formatted ASN.1 PKCS#8 representation of the key itself. Some can use the following web service to extract its contents (ASN1JS).
The KEY itself is 32 bytes long and is used to create the required ECDSA P-256 SHA-256 signature for the JWT. The resulting JWT looks like this '{JWT header base64 encoded}.{JWT payload base64 encoded}.Signature (64 bytes) base64 encoded'.
There are a lot of web services to decode such tokens, but some couldn't check the signature, as the corresponding PUBLIC KEY isn't known (Apple keeps it secret when providing the PRIVATE KEY).
EDIT: It seems, that the PUBLIC KEY is also included in the .p8 file, it can be extracted via OpenSSL (and is visible when decoding the ASN.1 content: the 520 bit stream).
openssl ec -in AuthKey_123ABC4567.p8 -pubout -out
AuthKey_123ABC4567_Public.p8
File extensions are just a convention, but most likely the .p8 extension is used to indicate that it is a PKCS#8 PrivateKeyInfo (or EncryptedPrivateKeyInfo).
I'd expect the Keychain program to be able to open it as "a key", but not having a mac at hand I can't say. It should open with SecItemImport (kSecFormatOpenSSL, kSecItemTypePrivateKey).
Is there a way to convert it to .pem or .p12?
Assuming you mean "certificate" by .pem, no. If you mean PEM encoded, sure. It's either "BEGIN PRIVATE KEY" or "BEGIN ENCRYPTED PRIVATE KEY", depending.
It can also, technically, be converted into a PKCS#12. But Apple's PKCS#12 importer won't import (last I saw) private keys that it can't figure out what certificate they belong with (from the same PKCS#12).
This is just a private key, there's no certificate (thus no expiration). So certificate-based approaches don't make sense.
Does the server side can operate with .p8 the same way as .p12 or it should be additional tools added?
This depends entirely on the details of the protocol, which I don't know. If the protocol transported the certificate then different machinery is involved with the conversion. If it just transported a signature and the server looked up the public key for verification then nothing changed server side.
It's a text file! The .p8 extension signifies a simple text file containing public/private key. You can open it with any text editor (TextEdit, vim, Sublime Text) to see your key.

What is Apple's certificate?

I'm trying to understand what the certificate is. I'm talking about the .cer file.
In the description it sounds like it is a public key but if it is, than why do I need Certificate Signing Request (CSR) when creating it?
Everywhere I can find "what is a developer certificate for" and so on, but there is no information what the certificate — as an entity — is.
So my questions are:
What is .cer file? (Not .p12)
What is the difference between certificate and public key?
1) The .cer is an commonly used extension for certificates.
Certficates are digitaly signed and encoded documents. To my understanding certificates are documents which contain data (strings etc.) and are encoded. Simply put it is a container for sensitive data.
For details read: DER vs CRT vs CRM vs PEM
2) The public key simply put is a value (String for example). This value is stored in a certificate .cer file.
For better understanding this video might help: Private and public key
The difference is that a certificate can contain a public key but a public key cannot contain a certificate.
A certificate certify who you are, its a kind of identity card or passport or whatever. A public key is something used to secure something, somehow like a real key closes a safety box not to let everyone have look inside.
Then you may have the need to certify that a public key is the one it claims. A certificate is (normally) obtained from another trusted authority (like your passport is delivered by a legal entity). If not how would you trust a public key I'll give to you? It can be a hacked public key, but if you have a certificate that belongs to it, then (if you trust the authority) you'll know it's really mine and not a forged one.
You may read Public Key Certificate on Wikipedia for example.
.cer files are certificates in some well defined format.

Is it possible to generate certificate signing request(.csr) using security framework in iOS?

I would like to make HTTPS request with a server require client-certificate authentication. I looked into this Creating a SecCertificateRef for NSURLConnection Authentication Challenge. It worked as expected.
However, it needs to prepare the p12 file which includes the private key. It would be secured as it needs a password to import the p12 file using SecPKCS12Import().
However, there could be other option. That is the iOS-client should make a certificate signing request(.CSR) and let a third party (the server) sign it.
For my search, I see that I can use SecKeyGeneratePair() for generating a key pair. But I don't see any API that generate a CSR.
Do I really need OpenSSL to achieve this?
Also, a bit off topic, once the iOS-client somehow receives the signed certificate. I can use SecCertificateCreateWithData() to retrieve an SecCertificateRef(). However, to fill in a NSURLCredential. I also need the SecIdentityRef which come from p12 file using SecPKCS12Import(). How can I retrieve a SecIdentityRef without SecPKCS12Import() but just a certificate file like crt or der?
There is no explicit support for CSR in Security Framework in iOS. However, it is not that difficult to build CSR 'manually' - it is just ASN.1 DER block of data that are available at iOS runtime.
Here is pseudo code of that:
Use SecKeyGeneratePair() from Security Framework to create fresh public/private key
Implement getPublicKeyBits method to retrieve NSData-form of fresh public key (see https://developer.apple.com/library/ios/samplecode/CryptoExercise/Introduction/Intro.html )
Implement getPrivateKey method to retrieve SecKeyRef from Keychain
Follow http://www.ietf.org/rfc/rfc2986.txt to construct ASN.1 DER of CSR in NSMutableData
Use CC_SHA1_* to create signature hash of Certification Request Info (part of CSR)
Use SecKeyRawSign and private key to sign CSR
This will create proper CSR (in form of NSData) that can be sent to CA for approval.
My implementation is available on GitHub: http://github.com/ateska/ios-csr .
To anyone who comes across this in the future, I encountered outfoxx's Shield library which makes it super easy to create CSRs via Swift.

Recover signing certificate without p12 password?

I've been handed an iOS app codebase, which I'd like to distribute via the existing Enterprise certificate used by the prior developer.
After importing the provided .mobileprovision file, I'm (not unsurprisingly) getting the "Valid signing identity not found" error. Specifically when building:
The identity '[name]' doesn't match any valid, non-expired certificate/private key pair in your keychains
I was given the original CertificateSigningRequest.certSigningRequest file, a .p12 file, and the .cer file. I was not given the password to the .p12 file.
Is it possible to rebuild what I need from the CertificateSigningRequest.certSigningRequest without the .p12 file's password? I can likely get the .p12 password, but not in a timely manner.
Thanks!
I recognize that you've solved your issue by getting the password for the .p12 file, but I thought I'd shine a little light on what lives in each of those files you mentioned for the benefit of anyone running across the question in the future.
To answer the main question in this question: Can I rebuild what I need from the CertificateSigningRequest.certSigningRequest file?
Regrettably the answer is a very solid 'No'. The root cause of this is the very heart of Public Key Infrastructure (PKI), a set of management technologies, people, and practices dealing with the creation, verification, use, and revocation of digital certificates. Central to PKI is the notion of a public-private key pair. The 'Public' key is the one you share widely, anyone may have a copy of it and anyone wishing to validate messages signed by a digital certificate will require access to this key. The 'Private' key is the linked key that only you (or more accurately, your machine) knows and uses when signing messages. It is this signature that is verified via use of the 'Public' key that is shared widely authenticating that the message is in fact authentic.
When we are constructing development or distribution certificates, we are inherently asking Keychain Access, openssl, or your preferred SSL toolchain to create a public-private key pair. The public key goes into the CertificateSigningRequest file along with the other 'Subject' fields like name and email address and we ship this file off to Apple. That file primarily tells Apple what Public Key they can use to validate your app signature -- it does not give them a copy of your Private Key after all, if others had your private key they'd be able to codesign as you effectively destroying the notion of accountability on the iOS platform (ex. This App's signature checks out as valid, but I still don't know if it was actually signed by a developer I trust...). At no point in time, is your Private Key transmitted to Apple or the Developer Portal; it resides quite happily in your Keychain until such a time as 1) The certificate expires, 2) you actively revoke the certificate from the Developer Portal, or 3) you accidentally (or intentionally) delete the keypair from Keychain.
So what lives in each of these files?
CertificateSigningRequest.certSigningRequest - This contains a copy of the Public Key from the Public-Private keypair you generated locally, plus some additional required subject information required by the Certificate Signing Request format. Apple disregards this additional information and uses the name and email address they have on file for your Developer Account when constructing your certificate.
.p12 - This is a PKCS#12 formatted file containing a copy of the Apple-issued Certificate (which itself contains the Public Key) and a copy of the linked Private Key. This data is encrypted to prevent unauthenticated access and thus requires a password to decrypt.
.cer - This is the Apple-issued Certificate that contains the Public key portion of the key pair. This certificate is used by Apple to validate that Apps you submit are not tampered with while in transit to the App Store review team:
You sign your app using the Private key that only you know and upload the signed binary to Apple.
Apple then validate the signature using the public key that you've already shared with them.
If the math works out, then the App hasn't been tampered with and you are good to go.
If the math doesn't work out, either the app was tampered with, or (much more likely) the certificate was revoked or regenerated and the app was signed with an old or incorrect key pair.
As you can see, the only places the Private Key resides is in the original developer's keychain as well as the encrypted .p12 file. Consistent with both your comment and flup's comment, you either have to get the password to that .p12 file or look into breaking through the encryption.
Regardless, good to hear that you were able to get the password from the original developer. Let me know if you have any followup questions.

Resources