从字符串中加载Jira公共证书 (.Net中如何将ASN.1编码的SubjectPublicKeyInfo转换为X509证书)

3
我正在构建一个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是一个开源类,在此处找到:

https://studio.atlassian.com/source/browse/OAUTH/trunk/api/src/main/java/com/atlassian/oauth/util/RSAKeys.java?r=HEAD

我希望将这个公共证书(密钥)加载到 .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,base64编码(162个字节未编码),这是使用java.security.PublicKey.getEncoded()在Java中的默认输出。

所以,考虑到所有这些 - 是否有任何简单的方法创建一个包装此公钥的X509Certificate2实例 - 或者除了公钥之外是否需要其他元数据来创建x509Certificate2实例?

2个回答

0
Jira应该为您提供一个证书(而不仅仅是公钥)。
通常,Java世界会提供一个Base64编码或PEM证书。.Net的X509Certificate2可以自动加载Base64、PEM或二进制证书。

0

您可以使用RSACryptoServiceProvider在.NET中生成XML RSA证书。这将为您提供XML(通过FromXmlString方法),公钥需要进行编码,例如使用此服务:

https://superdry.apphb.com/tools/online-rsa-key-converter

然后用它来创建链接到JIRA的应用程序。

您之前获得的XML形式的私钥可以直接用于签名.NET应用程序请求。

我个人使用了DonNetAuth库进行签名,令牌交换等操作,并且它对我很有效。我遇到的唯一问题是关于jql查询,需要稍微调整签名才能正常工作。这里是链接:

http://samondotnet.blogspot.sk/2012/12/introduction-to-dotnetauth.html

此外,请查看以下链接: https://answers.atlassian.com/questions/172760/is-there-any-jira-oauth-implementation-example-in-net

希望这能有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接