我正在构建一个 oauth 1.0a 服务,该服务将由 Jira 中的小工具使用,它是一个用 C# 编写的 .Net 3.5 应用程序。
Jira 使用 RSA-SHA1 签名方法向该服务发出请求,这意味着验证请求的签名我需要从他们的公共证书创建一个 X509Certificate 实例。
在 Jira 应用程序中,您可以通过转到消费者信息屏幕(其中还有 Jira 等的消费者密钥)来获取公共证书,它以这种格式显示公共密钥:
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCObJRTGSZbAo
jRkvKmm0cwFXnKcPMfR4t/sghvLe/+QVs6TJOz5cUh5UokSqyz
VeMsL0jomP18ZcR3SPcIFT7xtOGQjLwLk7ghfYSsxjTGs9VxsC
/PQk5OQRP3v43IxFNF3M2SYhFWJZTOnqrab5AsMh2Kxdv+D69D
CINXCu5ltQIDAQAB
查看生成此密钥的 Jira 代码,我可以看到它(据说)是 PEM 编码的,没有 BEGIN/END 证书页眉/页脚。
RSAKeys.toPemEncoding(consumer.getPublicKey())
RSAKeys 是一个开源类,可以在这里找到:
我希望将此公共证书(密钥)加载到 .Net 中的 X509Certificate 实例中,但到目前为止我的尝试都失败了。这是我的代码:
static readonly Regex stripRegex = new Regex("-----[A-Z ]*-----");
public string ConvertFromOpenSsl(string key)
{
return stripRegex.Replace(key, "").Replace("\r", "").Replace("\n", "");
}
public X509Certificate2 GetConsumerCertificate(IConsumer consumer)
{
string cert =
@"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCObJRTGSZbAo
jRkvKmm0cwFXnKcPMfR4t/sghvLe/+QVs6TJOz5cUh5UokSqyz
VeMsL0jomP18ZcR3SPcIFT7xtOGQjLwLk7ghfYSsxjTGs9VxsC
/PQk5OQRP3v43IxFNF3M2SYhFWJZTOnqrab5AsMh2Kxdv+D69D
CINXCu5ltQIDAQAB";
string converted = ConvertFromOpenSsl(cert);
var bytes = Convert.FromBase64String(converted);
var cert = new X509Certificate2(bytes); // throws here
但是在最后一行代码中,我抛出了一个异常:
System.Security.Cryptography.CryptographicException: Cannot find the requested object.
at System.Security.Cryptography.CryptographicException.ThrowCryptogaphicException(Int32 hr)
at System.Security.Cryptography.X509Certificates.X509Utils._QueryCertBlobType(Byte[] rawData)
at System.Security.Cryptography.X509Certificates.X509Certificate.LoadCertificateFromBlob(Byte[] rawData, Object password, X509KeyStorageFlags keyStorageFlags)
at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(Byte[] data)
at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(Byte[] rawData)
我很确定我错过了一些基本的东西,但我能想到它是什么。
更新
好的,经过进一步调查,这似乎是公钥的 SubjectPublicKeyInfo 序列化,所以它是 ASN.1,base 64 编码(162 字节未编码),这是 Java 使用 java.security.PublicKey.getEncoded() 的默认输出.
因此,鉴于所有这些 - 是否有任何简单的方法来创建包装此公钥的 X509Certificate2 实例 - 或者除了公钥之外还需要额外的元数据来创建 x509Certificate2 实例?