0

설치된 인증서로 XML 문서에 서명하는 데 문제가 있습니다. 인증서 파일 (.pfx)을 사용하여 X509Certificate2의 LocalMachine, CurrentUser 및 Initialize 인스턴스에 설치된 인증서로 시도했습니다. 각각에는 그것의 자신의 문제점이있다; 내 기본 설정은 LocalMachine 저장소에 설치된 인증서를 사용하는 것입니다. 나는 세 가지 방법과 각각 우려 설명했다 아래 :X.509 인증서가 설치된 xml 문서에 서명

StoreLocation LocalMachine - 선호하는 방법을

var certStore = new X509Store(StoreLocation.LocalMachine); 
certStore.Open(OpenFlags.ReadOnly); 
var certCollection = certStore.Certificates.Find(X509FindType.FindByThumbprint, certificateThumbPrint, true); 
var myCert = certCollection[0]; 

// I can get the correct certificate but the following line throws "Invalid provider type specified." error 
var SigningKey = myCert.PrivateKey; 

StoreLocation CurrentUser

var certStore = new X509Store(StoreLocation.CurrentUser); 
certStore.Open(OpenFlags.ReadOnly); 
var certCollection = certStore.Certificates.Find(X509FindType.FindByThumbprint, certificateThumbPrint, true); 
var myCert = certCollection[0]; 

// I can get the correct certificate but the following line throws "Keyset does not exist" error 
var SigningKey = myCert.PrivateKey; 

내가 만약 내가 단지의 PrivateKey를 얻을 수 있습니다 사용 권한을 % ALLUSERSPROFILE % \ Application Data \ Microsoft \ Crypto \ RSA \ MachineKeys 폴더로 변경하십시오. 이것은 서명을 구현하는 올바른 방법으로 보이지 않습니다. 인증서 파일

var certificateFile = @"C:\CertificateFolder\AuthorizedCertificate.pfx"; 
var myCert = new X509Certificate2(certificateFile, password, X509KeyStorageFlags.UserKeySet); 

이 방법을 사용하여

그러나 내가 인증서 파일과으로 바람직하지 않은 암호를 제공해야 할 것 작동합니다.

첫 번째 방법 (LocalMachine)을 작동 시키려면 어떻게해야합니까? 이 작업을 수행하는 데 권장되는/최선의 방법은 무엇입니까?

은 참고 다음 코드는

private void SignXml(XmlDocument xmlDoc, X509Certificate2 cert) 
{ 
    // Create a SignedXml object. 
    SignedXml signedXml = new SignedXml(xmlDoc); 

    // Add the key to the SignedXml document. 
    signedXml.SigningKey = cert.PrivateKey; 

    // Create a reference to be signed. 
    Reference reference = new Reference(); 
    reference.Uri = ""; 

    // Add an enveloped transformation to the reference. 
    var env = new XmlDsigEnvelopedSignatureTransform(); 
    reference.AddTransform(env); 

    // Include the public key of the certificate in the assertion. 
    signedXml.KeyInfo = new KeyInfo(); 
    signedXml.KeyInfo.AddClause(new KeyInfoX509Data(cert, X509IncludeOption.WholeChain)); 

    // Add the reference to the SignedXml object. 
    signedXml.AddReference(reference); 

    // Compute the signature. 
    signedXml.ComputeSignature(); 

    // Get the XML representation of the signature and save 
    // it to an XmlElement object. 
    XmlElement xmlDigitalSignature = signedXml.GetXml(); 

    // Append the element to the XML document. 
    xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true)); 
} 

답변

0

LocalMachine 저장소 버전

var SigningKey = myCert.GetRSAPrivateKey(); 

var SigningKey = myCert.PrivateKey; 

를 교체 XML 문서를 서명하는 데 사용됩니다

(S// 적절한 RSA/DSA)

PrivateKey의 속성에만 RSACryptoServiceProvider 또는 DSACryptoServiceProvider 스트있는 키를 반환 할 수있다. "잘못된 공급자 유형이 지정되었습니다."는 개인 키가 CAPI가 아니라 CNG에 저장됨을 의미합니다.

.NET 4.6.2 이상이 설치된 경우에만 작동합니다. SignedXml 및 해당 도우미 클래스 내의 특정 제한 사항 (RSAC가 아닌 RSACryptorServiceProvider RSA와 관련하여)이 수정 되었기 때문입니다.

(대안 : OS가이 문제를 해결하기 위해 CNG 브리지에 CAPI를 추가 윈도우 10로 업그레이드)

CurrentUser 저장소 버전

당신이 PFX에서 인증서를 가져올 때 가져온 때문에이 버전은 실패 MachineKeySet과 함께 (또는 UserKeySet을 지정하지 않고 이전에 머신 키 저장소에서 내 보낸 경우). 사용자 저장소에있는 인증서 사본에는 컴퓨터 저장소에있는 개인 키의 수명이 기록되어 있습니다. 그리고, 어떤 이유로 든, 당신은 그것에 접근 할 수 없습니다. ("어떤 이유로 든"당신이 그것을 추가 할 수 없다고 제안하기 때문에 ...)

PFX 버전

PFX 키가 인증서의 PrivateKey 속성이 작동하도록하는 CAPI CSP (PFXes 메타 데이터를 많이 수행)에 저장해야한다고 말한다 때문에 작동

.

+0

설명해 주셔서 감사합니다. myCert.GetRSAPrivateKey() .Net Framework 4.6.1과 함께 작업했지만 코드 (signedXml.ComputeSignature())의 다른 부분에서 다음 오류가 발생하여 도움을 받기를 바랍니다. System.NotSupportedException 메서드가 지원되지 않습니다. System.Security.Cryptography.RSA.DecryptValue (Byte [] rgb)에서 Byte [] DecryptValue (Byte []) at System.Security.Cryptography.Xml.SignedXml.ComputeSignature() – imran

+0

@imran 4.6.2을 필요로합니다. 대답에서 설명했다. – bartonjs

관련 문제