Search code examples
c#.netwindowsauthenticationcertificate

WindowsCryptographicException


I have this problem, when I run the following code in .net 3.0, in debbuging mode VisualStudio 2019, on Windows 10 S.O.

var iat = Math.Round((DateTime.UtcNow.AddMinutes(-1) - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds, 0);
var exp = Math.Round((DateTime.UtcNow.AddMinutes(60) - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds, 0);

        var payload = new Dictionary<string, object>()
        {
            { "iat", iat },
            { "exp", exp }
        };
        var extraHeader = new Dictionary<string, object>()
        {
            { "alg", "ES256" }
        };

        // private
         var keyString = "MIGkAgEBBDAIam72yz6+Yc8oR4z3OGUp7GRnpKyo5aDDztHFCclxfND8lxCHSPrmIVyMEHiLtumgBwYFK4EEACKhZANiAATtj95dxIpKztIMNnWsT9nZISdhAAWt/aQGOWaEScwaaFGrB/3/8ISytsIcMpIqA+cr7owlF+fhYjlF50gYOewpJgTHAsJnMUHNO+TA3ghTibQsJIGZSOqCsHSNaijWzmc=";

         //TO DO  CngKeyBlobFormat.Pkcs8PrivateBlob Error during Import
         CngKey privateKey = CngKey.Import(Convert.FromBase64String(keyString), CngKeyBlobFormat.Pkcs8PrivateBlob, CngProvider.MicrosoftSmartCardKeyStorageProvider);

on the last row I receive this error:

Internal.Cryptography.CryptoThrowHelper.WindowsCryptographicException: 'Error douring coiding or decoding.

What does it mean? How can I fix it?


Solution

  • The particular value here isn't a PKCS#8 PrivateKeyInfo payload, it looks like an ECPrivateKey value.

    https://lapo.it/asn1js/#MIGkAgEBBDAIam72yz6-Yc8oR4z3OGUp7GRnpKyo5aDDztHFCclxfND8lxCHSPrmIVyMEHiLtumgBwYFK4EEACKhZANiAATtj95dxIpKztIMNnWsT9nZISdhAAWt_aQGOWaEScwaaFGrB_3_8ISytsIcMpIqA-cr7owlF-fhYjlF50gYOewpJgTHAsJnMUHNO-TA3ghTibQsJIGZSOqCsHSNaijWzmc

    SEQUENCE (4 elem)
      INTEGER 1
      OCTET STRING (48 byte) 086A6EF6CB3EBE61CF28478CF7386529EC6467A4ACA8E5A0C3CED1C509C9717CD0FC97…
      [0] (1 elem)
        OBJECT IDENTIFIER 1.3.132.0.34 secp384r1 (SECG (Certicom) named elliptic curve)
      [1] (1 elem)
        BIT STRING (776 bit) 0000010011101101100011111101111001011101110001001000101001001010110011…
    

    That looks like ECPrivateKey

    ECPrivateKey ::= SEQUENCE {
      version        INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
      privateKey     OCTET STRING,
      parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
      publicKey  [1] BIT STRING OPTIONAL
    }
    

    VS a PKCS#8 PrivateKeyInfo

    PrivateKeyInfo ::= SEQUENCE {
        version                   Version,
        privateKeyAlgorithm       PrivateKeyAlgorithmIdentifier,
        privateKey                PrivateKey,
        attributes           [0]  IMPLICIT Attributes OPTIONAL }
    
    Version ::= INTEGER
    PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
    PrivateKey ::= OCTET STRING
    Attributes ::= SET OF Attribute
    

    For it to be a PKCS#8 you'd have the current value (ECPrivateKey) as the value of the PrivateKeyInfo.privateKey field.

    --

    Also, please note that you've posted a private key to the internet, so it's now compromised and shouldn't be used for anything other than testing now.