.Net, XmlDSigEx: CngKey.import с использованием открытого ключа из X509Certificate2 - PullRequest
3 голосов
/ 21 декабря 2011

Я пытаюсь проверить подписи XML, подписанные с помощью алгоритмов ECDsa.Я основываю свою работу на библиотеке XmlDSigEx, которую я должен немного изменить в соответствии со своими потребностями. Моя нынешняя проблема связана с получением открытого ключа из сертификата и использованием его в качестве CngKey. Я использовал:

// var cert = X509Certificate2 ...
var key = CngKey.Import(cert.GetPublicKey(), CngKeyBlobFormat.EccPublicBlob);

, который выдает «Параметр неверен».Я не смог найти какую-либо информацию о том, какой формат открытого ключа предполагается передать в качестве ключа.Поэтому я прошу помощи по этому вопросу: Как передать открытый ключ, хранящийся в сертификате X509, в CngKey?

TIA, Alois

PS: я подумалиспользовать BouncyCastle для извлечения открытого ключа.Я попытался

X509Certificate.CertificateStructure.SubjectPublicKeyInfo.GetEncoded()

BC, а также

X509Certificate.CertificateStructure.SubjectPublicKeyInfo.PublicKeyData.GetBytes()

, чтобы передать ключ CngKey;однако возникает та же ошибка.

1 Ответ

0 голосов
/ 23 февраля 2012

Я боролся с тем же типом проблемы, но использовал BouncyCastle для C # и пытался импортировать ключи в CngKey.ECDsaCng поддерживает формат XML RFC4050 для импорта с открытым ключом.Мне удалось импортировать ключи, сгенерированные с помощью BouncyCastle, используя приведенный ниже код, и проверить хэши с помощью ECDsaCng, которые были сгенерированы с помощью BouncyCastle.

//Specify which curve we are using   
string theCurveName = "prime256v1";

X509Certificate2 x509cert = null; //get your x509 certificate here...

//BouncyCastle publickey creation from certificate publickey
var namedCurve = X962NamedCurves.GetByName(theCurveName);

ECPublicKeyParameters publickey = new ECPublicKeyParameters("ECDSA",
    namedCurve.Curve.DecodePoint(x509cert.GetPublicKey()), // Q
    X962NamedCurves.GetOid(theCurveName));

//now we have the public key in bouncy castle
//we can create the xml to import to CngKey            
//Prime256v1 = 1.2.840.10045.3.1.7

var xmlImport = @"<ECDSAKeyValue xmlns='http://www.w3.org/2001/04/xmldsig-more#'>
  <DomainParameters>
    <NamedCurve URN='urn:oid:" + X962NamedCurves.GetOid(theCurveName).Id + @"' />
  </DomainParameters>
  <PublicKey>
    <X Value='" + publickey.Q.X.ToBigInteger().ToString() + @"' xsi:type='PrimeFieldElemType' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' />
    <Y Value='" + publickey.Q.Y.ToBigInteger().ToString() + @"' xsi:type='PrimeFieldElemType' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' />
  </PublicKey>
</ECDSAKeyValue>";

var eccImporter = new ECDsaCng();
eccImporter.FromXmlString(xmlImport, ECKeyXmlFormat.Rfc4050);


//prep bouncy castle signature to single array
var sig0 = sig[0].ToByteArrayUnsigned();
var sig1 = sig[1].ToByteArrayUnsigned();   
byte[] newSig = new byte[sig0.Length + sig1.Length];
sig0.CopyTo(newSig, 0);
sig1.CopyTo(newSig, sig0.Length);

var isok = eccImporter.VerifyHash(manualhash, newSig);
...