从字符串加载.Net中的Jira公共证书(如何将ASN.1编码的SubjectPublicKeyInfo转换为.Net中的X509证书)
我正在构建一个 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 实例?
I am building an oauth 1.0a service that will be consumed by a gadget within Jira, it's a .Net 3.5 Application written in C#.
Jira makes requests to this service using the RSA-SHA1 signature method, which means to verify the signature of the request I need create an X509Certificate instance form their public cert.
Within the Jira application you can get the public cert by going to the consumer info screen (which also has the consumer key for Jira etc.) and it presents the public key in this format:
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCObJRTGSZbAo
jRkvKmm0cwFXnKcPMfR4t/sghvLe/+QVs6TJOz5cUh5UokSqyz
VeMsL0jomP18ZcR3SPcIFT7xtOGQjLwLk7ghfYSsxjTGs9VxsC
/PQk5OQRP3v43IxFNF3M2SYhFWJZTOnqrab5AsMh2Kxdv+D69D
CINXCu5ltQIDAQAB
Looking at the Jira code which generates this key I can see it's (supposedly) PEM encoded without the BEGIN/END certificate header/footer.
RSAKeys.toPemEncoding(consumer.getPublicKey())
RSAKeys is an open source class found here:
I wish to load this public cert (key) into an X509Certificate instance within .Net, but my attempts so far have failed. Here's the code I have:
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
But on the last line of code I have an exception thrown:
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)
I'm pretty sure I am missing something elementary, but I can think what it is.
UPDATE
OK, on further investigation it appears that this is a SubjectPublicKeyInfo serialization of the public key, so it's ASN.1, base 64 encoded (162 bytes unencoded), which is the default output from Java using java.security.PublicKey.getEncoded().
So given all that - is there any easy way to create an X509Certificate2 instance wrapping this public key - or is additional metadata required beyond the public key to create an x509Certificate2 instance?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Jira 应该为您提供证书(而不仅仅是公钥)。
通常,Java 世界会提供 Base64 编码或 PEM 证书。来自.Net的X509Certificate2可以自动加载base64、PEM或二进制证书。
Jira should provide you with a Certificate (not just a public key).
Typically the Java world will give a base64 encoded or PEM certificate. X509Certificate2 from .Net can automatically .Load a base64, PEM or binary certificate.
您可以使用 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
希望这会有所帮助。
you can generate your XML RSA certificate via .NET using RSACryptoServiceProvider. This will give you XML (FromXmlString method), the public key then needs to be encoded, for example by using this service:
https://superdry.apphb.com/tools/online-rsa-key-converter
and then used to create application link to JIRA.
The private key in XML form you got previously, can be used for signing .NET app requests directly.
I personally used DonNetAuth library for signing, exchannging tokens, etc and it works for me. The only bug I encountered was regarding jql queries, where the signing needed a bit of tweaking to work correctly. Here is the link:
http://samondotnet.blogspot.sk/2012/12/introduction-to-dotnetauth.html
Additionally see this link:
https://answers.atlassian.com/questions/172760/is-there-any-jira-oauth-implementation-example-in-net
Hope this helps.