developer tip

X509Certificate 생성자 예외

copycodes 2020. 11. 6. 18:55
반응형

X509Certificate 생성자 예외


//cert is an EF Entity and 
//    cert.CertificatePKCS12 is a byte[] with the certificate.

var certificate = new X509Certificate(cert.CertificatePKCS12, "SomePassword");

데이터베이스에서 인증서를로드 할 때 스테이징 서버 (Windows 2008 R2 / IIS7.5)에서 다음 예외가 발생합니다.

System.Security.Cryptography.CryptographicException: An internal error occurred.

   at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr)
   at System.Security.Cryptography.X509Certificates.X509Utils._LoadCertFromBlob(Byte[] rawData, IntPtr password, UInt32 dwFlags, Boolean persistKeySet, SafeCertContextHandle& pCertCtx)
   at System.Security.Cryptography.X509Certificates.X509Certificate.LoadCertificateFromBlob(Byte[] rawData, Object password, X509KeyStorageFlags keyStorageFlags)

참고 : 이 문제는 로컬에서 발생하지 않습니다 (Windows 7 / Casini).

어떤 통찰력이라도 대단히 감사합니다.


IIS 응용 프로그램 풀 구성 (응용 프로그램 풀> 고급 설정)에 응용 프로그램 풀 ID 사용자에 대한 사용자 프로필을로드하는 설정이 있습니다. false로 설정하면 키 컨테이너에 액세스 할 수 없습니다.

따라서 Load User Profile옵션을 다음과 같이 설정하십시오.True

앱 풀-> 고급 설정 화면


Visual Studio / Cassini에서 실행 하는 경우 바이트에서로드하더라도 사용자 인증서 저장소에 액세스 할 가능성이 높습니다 . 이것을 시도하고 문제가 해결되는지 확인하십시오.

var certificate = new X509Certificate(
    cert.CertificatePKCS12, "SomePassword", X509KeyStorageFlags.MachineKeySet);

이로 인해 IIS (사용자 저장소에 액세스 할 수없는 ASP.NET 사용자로 실행 됨)가 컴퓨터 저장소를 사용하게됩니다.

이 페이지 에서는 생성자에 대해 자세히 설명 하고이 페이지 에서는 X509KeyStorageFlags열거 형에 대해 설명합니다 .

편집 : cyphr두 번째 링크기반으로, 다음과 같이 열거 형 값 중 일부를 결합하는 것이 좋은 생각 일 수 있습니다 (이전 솔루션이 작동하지 않는 경우) .FlagsAttribute

var certificate = new X509Certificate(
    cert.CertificatePKCS12, "SomePassword",
    X509KeyStorageFlags.MachineKeySet
    | X509KeyStorageFlags.PersistKeySet
    | X509KeyStorageFlags.Exportable);

또한 액세스 권한이있는 경우 LocalService를 사용하도록 응용 프로그램 풀 설정을 변경 한 다음 AppPool을 다시 시작할 수 있습니다. 이것이 문제인 경우 권한을 적절한 수준으로 높일 수 있습니다.

마지막으로를 사용 File.WriteAllBytes하여 CertificatePKCS12pfx 파일에 내용 을 기록하고 MMC에서 인증서 콘솔을 사용하여 수동으로 가져올 수 있는지 확인할 수 있습니다 (가져 오기 성공 후 삭제할 수 있습니다. 테스트 용입니다). 데이터가 손상되었거나 암호가 올바르지 않을 수 있습니다.


이 코드를 사용하십시오.

certificate = new X509Certificate2(System.IO.File.ReadAllBytes(p12File)
                                   , p12FilePassword
                                   , X509KeyStorageFlags.MachineKeySet |
                                     X509KeyStorageFlags.PersistKeySet | 
                                     X509KeyStorageFlags.Exportable);

I had trouble on Windows 2012 Server R2 where my application could not load certificates for a PFX on disk. Things would work fine running my app as admin, and the exception said Access Denied so it had to be a permissions issue. I tried some of the above advice, but I still had the problem. I found that specifying the following flags as the third parameter of the cert constructor did the trick for me:

 X509KeyStorageFlags.UserKeySet | 
 X509KeyStorageFlags.PersistKeySet | 
 X509KeyStorageFlags.Exportable

To be able really solve your problem and not just guess, what can it be, one need be able to reproduce your problem. If you can't provide test PFX file which have the same problem you have to examine the problem yourself. The first important question is: are the origin of the exception "An internal error occurred" in the private key part of the PKCS12 or in the public part of the certificate itself?

So I would recommend you to try to repeat the same experiment with the same certificate, exported without private key (like .CER file):

var certificate = new X509Certificate(cert.CertificateCER);

or

var certificate = new X509Certificate.CreateFromCertFile("My.cer");

It could help to verify whether the origin of your problem is the private key or some properties of the certificate.

If you will have problem with the CER file you can safe post the link to the file because it have public information only. Alternatively you can at least execute

CertUtil.exe -dump -v "My.cer"

or

CertUtil.exe -dump -v -privatekey -p SomePassword "My.pfx"

(you can use some other options too) and post some parts of the output (for example properties of the private key without the PRIVATEKEYBLOB itself).


An alternative to changing the Load User Profile is to make the Application Pool use the Network Service Identity.

See also What exactly happens when I set LoadUserProfile of IIS pool?


.cer 인증서를 로컬 컴퓨터 키 저장소로 가져와야합니다. .p12 인증서를 가져올 필요가 없습니다. 대신 Apple에서 계정에 발급 한 두 번째 인증서를 사용하세요. 유효한 인증서 쌍이어야한다고 생각합니다 (하나는 파일 시스템에, 두 번째는 키 저장소에 있음). 물론 dll에서 3 개의 플래그를 모두 설정해야합니다.

참고 URL : https://stackoverflow.com/questions/9951729/x509certificate-constructor-exception

반응형