Public Trusted Root Gives Error “The integrity of this certificate cannot be guaranteed”

 

 

I recently worked an odd case where customer was seeing the below error on some of his certificates in the Trusted Root Certificate Authority store. This was only the case for some certificates and happened on several different Operating Systems. The customer was thinking that something had corrupted the certificates but even downloading them from Verisign and importing them made no difference.

 

image

 

We asked customer to save that certificate to a file and then run a certutil command against it and send us the output. Command was certutil –verify SavedCert.cer > verify.txt

 

Below is the output from verify.txt

 

Issuer:
    OU=Class 3 Public Primary Certification Authority
    O=VeriSign, Inc.
    C=US
  Name Hash(sha1): 48b76449f3d5fefa1133aa805e420f0fca643651
  Name Hash(md5): 27b3517667331ce2c1e74002b5ff2298
Subject:
    OU=Class 3 Public Primary Certification Authority
    O=VeriSign, Inc.
    C=US
  Name Hash(sha1): 48b76449f3d5fefa1133aa805e420f0fca643651
  Name Hash(md5): 27b3517667331ce2c1e74002b5ff2298
Cert Serial Number: 70bae41d10d92934b638ca7b03ccbabf

dwFlags = CA_VERIFY_FLAGS_CONSOLE_TRACE (0x20000000)
dwFlags = CA_VERIFY_FLAGS_DUMP_CHAIN (0x40000000)
ChainFlags = CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT (0x40000000)
HCCE_LOCAL_MACHINE
CERT_CHAIN_POLICY_BASE
-------- CERT_CHAIN_CONTEXT --------
ChainContext.dwErrorStatus = CERT_TRUST_IS_NOT_SIGNATURE_VALID (0x8)
ChainContext.dwErrorStatus = CERT_TRUST_HAS_WEAK_SIGNATURE (0x100000)
SimpleChain.dwErrorStatus = CERT_TRUST_IS_NOT_SIGNATURE_VALID (0x8)
SimpleChain.dwErrorStatus = CERT_TRUST_HAS_WEAK_SIGNATURE (0x100000)

CertContext[0][0]: dwInfoStatus=c dwErrorStatus=100008
  Issuer: OU=Class 3 Public Primary Certification Authority, O="VeriSign, Inc.", C=US
  NotBefore: 1/28/1996 7:00 PM
  NotAfter: 8/1/2028 6:59 PM
  Subject: OU=Class 3 Public Primary Certification Authority, O="VeriSign, Inc.", C=US
  Serial: 70bae41d10d92934b638ca7b03ccbabf
  74 2c 31 92 e6 07 e4 24 eb 45 49 54 2b e1 bb c5 3e 61 74 e2
  Element.dwInfoStatus = CERT_TRUST_HAS_NAME_MATCH_ISSUER (0x4)
  Element.dwInfoStatus = CERT_TRUST_IS_SELF_SIGNED (0x8)
  Element.dwErrorStatus = CERT_TRUST_IS_NOT_SIGNATURE_VALID (0x8)
  Element.dwErrorStatus = CERT_TRUST_HAS_WEAK_SIGNATURE (0x100000)

Exclude leaf cert:
  da 39 a3 ee 5e 6b 4b 0d 32 55 bf ef 95 60 18 90 af d8 07 09
Full chain:
  74 2c 31 92 e6 07 e4 24 eb 45 49 54 2b e1 bb c5 3e 61 74 e2
  Issuer: OU=Class 3 Public Primary Certification Authority, O="VeriSign, Inc.", C=US
  NotBefore: 1/28/1996 7:00 PM
  NotAfter: 8/1/2028 6:59 PM
  Subject: OU=Class 3 Public Primary Certification Authority, O="VeriSign, Inc.", C=US
  Serial: 70bae41d10d92934b638ca7b03ccbabf
  74 2c 31 92 e6 07 e4 24 eb 45 49 54 2b e1 bb c5 3e 61 74 e2
A signature algorithm or public key length does not meet the system's minimum required strength. 0x80094016 (-2146877418)
------------------------------------
CertUtil: -verify command FAILED: 0x80094016 (-2146877418)
CertUtil: A signature algorithm or public key length does not meet the system's minimum required strength.

 

The last line had me thinking, okay what was done to this system that is not allowing it to use a self-signed certificate that is in the Trusted Root store? As you can see the Public Key length is 1024 (below).

 

image

I did some research and found this KB.

https://support.microsoft.com/en-us/kb/2661254

Using the above KB I realized that someone must have set a registry key that does not exist by default.

HKLM\Software\Microsoft\Cryptography\OID\EncodingType0\CertDllCreateCertificateChainEngine\Config and added DWORD minRSAPubKeyBitLength

They set it to at least 2048 which causes the above certificate to display the error about integrity.

You can find out if that registry key exists by running certutil -getreg chain\minRSAPubKeyBitLength and if it exists at all it will give a value. If it does not it will error (below).

 

image

You can set it using certutil -setreg chain\minRSAPubKeyBitLength <value> where value can be 512, 1024, 2048, 4096, etc. So certutil -setreg chain\minRSAPubKeyBitLength 2048 would set it to 2048 bits

To delete the key altogether use certutil -delreg chain\minRSAPubKeyBitLength

Once the key was deleted the error was no longer seen on any of Trusted Root Certificates.

 

Cheers!