1

I have downloaded a CSR from Azure Key Vault and wanted to recreate that CSR with openSSL commands. Reason is we might want to create that CSR from scripts without having an Azure KeyVault.

My context:

  • I Created a CSR in Azure KeyVault
  • I have a retrieved the private key that the KeyVault used to create the CSR.
  • I inspected the KeyVault generated CSR using openssl req -text -noout -verify -in csr.csr
  • I Created my own CSR using OpenSSL And made sure all the subject information and Requested Extensions are the same as the KeyVault one.

When inspecting the newly created CSR (using above command) and the one generated by Azure KeyVault, they are identical (e.g. same modulus, same request extensions, same subject) except for the signature.

My question: Are there components in a CSR that are not inspected using above command that can explain why the signatures are different while the rest is the same? Or is it because it is generated on a different machine? Or can it be they (KeyVault and OpenSSL) used different algorithms for sha256WithRSAEncryption which is not viewable with above inspection command? I'm trying to understand.

        Version: 1 (0x0)
        Subject: <<obf>>
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    <<obf>>
                Exponent: 65537 (0x10001)
        Attributes:
        Requested Extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage:
                TLS Web Server Authentication, TLS Web Client Authentication
            X509v3 Subject Alternative Name:
                DNS:<<obf>>
            X509v3 Basic Constraints:
                CA:FALSE
    Signature Algorithm: sha256WithRSAEncryption
         <<obf>>

XWIKO
  • 308
  • 4
  • 13
  • By the same private key, do you mean you had it outside of KeyVault and imported it in? Because AFAIK, you can't export a private key from a KeyVault. – Irwene Feb 07 '23 at 14:48
  • Yes you can, because the private keys of certificates are stored as secrets. e.g. `az keyvault secret download --file outfile --id https://mykv.vault.azure.net/secrets/{certname}/{certversion}`. Not widely known by everybody though. Some answers to that question states they cannot be retrieved. – XWIKO Feb 07 '23 at 14:49
  • Oh, explains things, didn't use KeyVault as a Certificate store yet. More to your question, would this https://stackoverflow.com/a/20575701/2245256 answer it ? TL;DR : two signature of the same data will be different for security purposes – Irwene Feb 07 '23 at 14:50
  • Thanks for the post. The thing however is when I locally keep creating that CSR, it generates the same signature everytime. Its just different from the KeyVault one. – XWIKO Feb 07 '23 at 14:53
  • The comments of the answer I linked explains why that could be. Basically: the "random" value could be created using a deterministic algorithm by whatever you use to generate your CSR on your machine. Would be interesting is to see if KeyVault does the same. – Irwene Feb 07 '23 at 14:58
  • The post is about DSA, and I'm using RSA in my signature using `sha256WithRSAEncryption` which is supposed to be deterministic as far as I can read everywhere. – XWIKO Feb 08 '23 at 09:24

1 Answers1

0

Answering 'Are there components in a CSR that are not inspected using above command that can explain why the signatures are different while the rest is the same?' There might be different padding schemes, or sequence of some fields.

To fully inspect binary/PEM encoded PKCS#10 CSR data use openssl asn1parse -i -in csr.csr on both CSRs. This will show not only show difference between some fields but will show full structure which might affect final signature.

nusch
  • 86
  • 4
  • I used a JavaScript decoder since OpenSSL did not work. I see that KeyVault uses `PrintableString` for 4 specific object types (i.e. localityName, organizationName, organizationalUnitName, commonName ), and my CSR uses `UTF8String` for those objects. Can that be the explanation? – XWIKO Feb 21 '23 at 09:32
  • The KV created CSR uses UTF8String for stateOrProvinceName and PrintableString for the other subject parts. Can I control the string types on a level that specific using OpenSSL? E.g. PrintableString for localityName and UTF8String for stateOrProvinceName? `string_mask`'s effect is a bit too broad. – XWIKO Feb 21 '23 at 10:24
  • Cryptographic signatures require exactly the same binary input to provide same output. Apart from the spec which probably clearly defines which exact method is righ, if you would like to mimic some specific behaviour of Microsoft code probably better idea would be to prepare low level template using e.g python pyasn1 library and they fill rest of the fields. Although this doesn't guarantee something on MS side won't change in future. – nusch Feb 21 '23 at 17:40
  • Yes you are right. I just wanted to know what caused the difference, and inspecting the output using the JavaScript decoder it is very clear that this usage of different string types causes the difference. Thank you. – XWIKO Feb 22 '23 at 13:55