Я пытаюсь подписать некоторые данные с помощью сертификата PKCS # 12, однако у меня проблема с получением закрытого ключа из файла PKCS # 12 (.p12).
public byte[] sign(string text)
{
string password = "1111";
X509Certificate2 cert = new X509Certificate2("c:\\certificate.p12",password);
byte[] certData = cert.Export(X509ContentType.Pfx,password);
X509Certificate2 newCert = new X509Certificate2(certData, password);
RSACryptoServiceProvider crypt = (RSACryptoServiceProvider)newCert.PrivateKey;
SHA1Managed sha1 = new SHA1Managed();
UnicodeEncoding encoding = new UnicodeEncoding();
byte[] data = encoding.GetBytes(text);
byte[] hash = sha1.ComputeHash(data);
return crypt.SignHash(hash, CryptoConfig.MapNameToOID("SHA1"));
}
Проблема в том, что newCert.PrivateKey имеет значение null, но если я использую .pfx certicitae, то он работает.
public byte[] sign(string text)
{
string password = "1234";
X509Certificate2 cert = new X509Certificate2("c:\\certificate.pfx", password);
RSACryptoServiceProvider crypt = (RSACryptoServiceProvider)cert.PrivateKey;
SHA1Managed sha1 = new SHA1Managed();
UnicodeEncoding encoding = new UnicodeEncoding();
byte[] data = encoding.GetBytes(text);
byte[] hash = sha1.ComputeHash(data);
return crypt.SignHash(hash, CryptoConfig.MapNameToOID("SHA1"));
}
Итак, вопрос в том, как получить этот закрытый ключ из файла .p12?
У меня была аналогичная проблема, которую я разместил здесь, хотя это не то же самое для вас, проблема может быть и разрешениями.
Мои предложения: во-первых, вы должны убедиться (что, я полагаю, вы уже сделали), что закрытый ключ является экспортируемым, и у вас есть права на файл.
Затем попробуйте экспортировать тип контента как X509ContentType.Pkcs12
вместо X509ContentType.Pfx
Наконец, если это возможно, почему бы вам не попробовать импортировать его в certstore. Я считаю, что это более безопасно. Этапы приведены в ссылке выше.
X509ContentType.Pkcs12
но с тем же результатом. Хотя импортирование этого в certstore может быть решением.
Это было сделано для использования Android - таким образом, R.raw.key ниже был моим файлом в папке Android Raw.
Я открыл key.p12 как входной поток. Затем я преобразовал в закрытый ключ, используя библиотеки, как показано в примере.
http://www.flexiprovider.de/examples/ExampleSMIMEsign.html
Мой код выглядит следующим образом
Security.addProvider(new de.flexiprovider.core.FlexiCoreProvider());
// Next, we have to read the private PKCS #12 file, since the the
// private key used for signing is contained in this file:
DERDecoder dec = new DERDecoder(getResources().openRawResource(
R.raw.key));
PFX pfx = new PFX();
try {
pfx.decode(dec);
SafeBag safeBag = pfx.getAuthSafe().getSafeContents(0)
.getSafeBag(0);
PKCS8ShroudedKeyBag kBag = (PKCS8ShroudedKeyBag) safeBag
.getBagValue();
char[] password = "my password for the p12".toCharArray();
privKey = kBag.getPrivateKey(password);
new AsyncLoadStorage(this).execute();
} catch (ASN1Exception e) {
В docs говорится, что .export()
не поддерживает тип Pfx
, только Cert
, SerializedCert
, и Pkcs12
.
Посмотрите этот вопрос. Он выглядит очень похожим.