WinRT中 导入X509 RSA公钥时问题
来源:互联网 发布:h3c网络安全工程师 编辑:程序博客网 时间:2024/05/06 10:21
最近开发WinRT应用时,需要使用服务端提供的公钥加密,可总出现:“ASN1 bad tag value met.”,错误提示。寻寻觅觅多时未找到解决方案。最后终于在一个国处的论坛找到一种解决办法。
链接地址为:https://social.msdn.microsoft.com/Forums/en-US/17e1467a-2de7-47d2-8d8c-130518eaac68/how-to-use-a-x509-certificate-not-a-pfx-to-verify-a-signature
出错位置在以下语句,即加载公钥的地方:
IBuffer keyBuffer = CryptographicBuffer.DecodeFromBase64String(publicKey);AsymmetricKeyAlgorithmProvider asym = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithmNames.RsaPkcs1);CryptographicKey key = asym.ImportPublicKey(keyBuffer, CryptographicPublicKeyBlobType.Pkcs1RsaPublicKey); // 出错
经过反复查阅论坛,得出一个结论,就是不要尝试直接使用public key,一定要进行解析转换才行,要不然,就只能要求服务端改变成适合于WinRT的形式再重新提供public key。
解析转换原文提供了源代码,使用其提供的函数,则上述代码替换如下即可:
</pre><pre name="code" class="csharp">CryptographicKey key = GetCryptographicPublicKeyFromCert(publicKey);
GetCryptographicPublicKeyFromCert 函数的提供源码如下:
public static CryptographicKey GetCryptographicPublicKeyFromCert(string strCert) { int length; CryptographicKey CryptKey = null; byte[] bCert = Convert.FromBase64String(strCert); // Assume Cert contains RSA public key // Find matching OID in the certificate and return public key byte[] rsaOID = EncodeOID("1.2.840.113549.1.1.1"); int index = FindX509PubKeyIndex(bCert, rsaOID, out length); // Found X509PublicKey in certificate so copy it. if (index > -1) { byte[] X509PublicKey = new byte[length]; Array.Copy(bCert, index, X509PublicKey, 0, length); AsymmetricKeyAlgorithmProvider AlgProvider = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithmNames.RsaPkcs1); CryptKey = AlgProvider.ImportPublicKey(CryptographicBuffer.CreateFromByteArray(X509PublicKey)); } return CryptKey; } static int FindX509PubKeyIndex(byte[] Reference, byte[] value, out int length) { int index = -1; bool found; length = 0; for (int n = 0; n < Reference.Length; n++) { if ((Reference[n] == value[0]) && (n + value.Length < Reference.Length)) { index = n; found = true; for (int m = 1; m < value.Length; m++) { if (Reference[n + m] != value[m]) { found = false; break; } } if (found) break; else index = -1; } } if (index > -1) { // Find outer Sequence while (index > 0 && Reference[index] != 0x30) index--; index--; while (index > 0 && Reference[index] != 0x30) index--; } if (index > -1) { // Find the length of encoded Public Key if ((Reference[index + 1] & 0x80) == 0x80) { int numBytes = Reference[index + 1] & 0x7F; for (int m = 0; m < numBytes; m++) { length += (Reference[index + 2 + m] << ((numBytes - 1 - m) * 8)); } length += 4; } else { length = Reference[index + 1] + 2; } } return index; } static public byte[] EncodeOID(string szOID) { int[] OIDNums; byte[] pbEncodedTemp = new byte[64]; byte[] pbEncoded = null; int n, index, num, count; OIDNums = ParseOID(szOID); pbEncodedTemp[0] = 6; pbEncodedTemp[2] = Convert.ToByte(OIDNums[0] * 40 + OIDNums[1]); count = 1; for (n = 2, index = 3; n < OIDNums.Length; n++) { num = OIDNums[n]; if (num >= 16384) { pbEncodedTemp[index++] = Convert.ToByte(num / 16384 | 0x80); num = num % 16384; count++; } if (num >= 128) { pbEncodedTemp[index++] = Convert.ToByte(num / 128 | 0x80); num = num % 128; count++; } pbEncodedTemp[index++] = Convert.ToByte(num); count++; } pbEncodedTemp[1] = Convert.ToByte(count); pbEncoded = new byte[count + 2]; Array.Copy(pbEncodedTemp, 0, pbEncoded, 0, count + 2); return pbEncoded; } static public int[] ParseOID(string szOID) { int nlast, n = 0; bool fFinished = false; int count = 0; int[] dwNums = null; do { nlast = n; n = szOID.IndexOf(".", nlast); if (n == -1) fFinished = true; count++; n++; } while (fFinished == false); dwNums = new int[count]; count = 0; fFinished = false; do { nlast = n; n = szOID.IndexOf(".", nlast); if (n != -1) { dwNums[count] = Convert.ToInt32(szOID.Substring(nlast, n - nlast), 10); } else { fFinished = true; dwNums[count] = Convert.ToInt32(szOID.Substring(nlast, szOID.Length - nlast), 10); } n++; count++; } while (fFinished == false); return dwNums; }
0 0
- WinRT中 导入X509 RSA公钥时问题
- X509证书中RSA公钥的提取与载入
- X509证书中RSA公钥的提取与载入 pem key
- 关于WinRT中c++和c#相互调用的问题
- 关于WinRT中c++和c#相互调用的问题
- WinRT下的RSA加解密方法
- 加密算法和文件格式RSA、X509、PKCSXX
- Openssl生成导入X509证书
- WinRT
- WinRT中读取基础数据类型
- 离散数学中RSA公钥算法问题
- WPF和WinRT中的导航问题
- 在.NET代码中调用WinRT api
- WinRT中 压缩/解压缩,加密/解密
- WinRT中实现元素拖拉效果
- WinRT中实现回到列表顶部功能
- 如何在 Qt中调用 WinRt API
- WinCE Security --- X509证书及私钥的导入
- linux环境下的一种退出后快速返回的方法
- 欢迎使用CSDN-markdown编辑器
- 算法
- Java内存
- Find Cycle
- WinRT中 导入X509 RSA公钥时问题
- Cocos2d-x开发系列 从一个图片灰态需求开始我的博客之旅
- 信号量例子
- 【Linux学习】epoll详解 http://blog.csdn.net/xiajun07061225/article/details/9250579
- 追求内心的自由
- bzoj1293【SCOI2009】生日礼物
- 临近的最小数
- 快速排序
- [LeedCode OJ]#238 Product of Array Except Self