数字证书验证的问题,高分!
是用usbKey从客户端数字签名后,再把签名后的信息返回到服务器中,再用服务器的数字证书来验证问题是怎样验证?
是X.509,用的算法应该是rsa,怎样利用证书的公钥来验证签名后的信息呢?
拜托了 --------------------编程问答-------------------- 帮顶up --------------------编程问答-------------------- 多谢上楼了
自己再UP --------------------编程问答-------------------- 你这问题太专业,估计会的人不多!
我也只能帮你鼎了! --------------------编程问答-------------------- 有意思。先mark --------------------编程问答-------------------- 顶
没使用过楼主说的算法! --------------------编程问答-------------------- 试一下下面的代码
using System;--------------------编程问答-------------------- 多谢cocosoft甴曱!
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Security.Cryptography.X509Certificates;
using System.Runtime.InteropServices;
using System.ComponentModel;
namespace WindowsApplication1
{
/// <summary>
/// 使用RSACryptoServiceProvider和X509Certificate2进行证书加密解密
/// 作者:cocosoft
/// 日期:2007-11-15
/// 平台:.NET 2.0
/// </summary>
public class CertificateEncryptedDecrypted
{
static string mDigitalCertificateName = "";
[Description("证书名称")]
public static string DigitalCertificateName
{
get
{
return mDigitalCertificateName;
}
set
{
mDigitalCertificateName = value;
}
}
/// <summary>
/// 获取密文
/// </summary>
/// <param name="cPlainStringToEncrypt">明文</param>
/// <returns></returns>
public static string GetEncryptedText(string cPlainStringToEncrypt)
{
X509Store store = new X509Store(StoreName.My);
X509Certificate2 x509_2 = null;
store.Open(OpenFlags.ReadWrite);
if (mDigitalCertificateName.Length > 0)
{
foreach (X509Certificate2 cert in store.Certificates)
{
if (cert.SubjectName.Name.Contains(mDigitalCertificateName))
{
x509_2 = cert;
break;
}
}
if (x509_2 == null)
throw new Exception("不能找到证书:" + mDigitalCertificateName);
}
else
{
x509_2 = store.Certificates[0];
}
try
{
string PlainString = cPlainStringToEncrypt.Trim();
byte[] cipherbytes = ASCIIEncoding.ASCII.GetBytes(PlainString);
RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)x509_2.PublicKey.Key;
byte[] cipher = rsa.Encrypt(cipherbytes, false);
return Convert.ToBase64String(cipher);
}
catch (Exception e)
{
throw e;
}
}
/// <summary>
/// 获取译文
/// </summary>
/// <param name="cEncryptedStringToDecrypt">密文</param>
/// <returns></returns>
public static string GetDecryptedText(string cEncryptedStringToDecrypt)
{
X509Store store = new X509Store(StoreName.My);
X509Certificate2 x509_2 = null;
store.Open(OpenFlags.ReadWrite);
if (mDigitalCertificateName.Length > 0)
{
foreach (X509Certificate2 cert in store.Certificates)
{
if (cert.SubjectName.Name.Contains(mDigitalCertificateName))
{
x509_2 = cert;
break;
}
}
if (x509_2 == null)
throw new Exception("不能找到证书:" + mDigitalCertificateName);
}
else
{
x509_2 = store.Certificates[0];
}
try
{
byte[] cipherbytes = Convert.FromBase64String(cEncryptedStringToDecrypt);
if (x509_2.HasPrivateKey)
{
RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)x509_2.PrivateKey;
byte[] plainbytes = rsa.Decrypt(cipherbytes, false);
System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
return enc.GetString(plainbytes);
}
else
{
throw new Exception("证书没有使用私钥");
}
}
catch (Exception e)
{
throw e;
}
}
}
}
你提供的例子好像只能在.net2.0中的,没有没.net1.1的 --------------------编程问答-------------------- 在.NET 1.1里面并不支持 X509Store及X509Certificate2,其中,X509Certificate2可使用X509Certificate来代替。不能使用X509Store,那么你可以使用如下代码来实现读取:
--------------------编程问答-------------------- // 建立需要校验的源,可自行选择编码格式,我的用的UTF8编码。
StreamReader reader = new StreamReader(path); //.cer文件路径
string certbody = reader.ReadToEnd();
certbody=certbody.Replace("-----END CERTIFICATE-----","");
certbody=certbody.Replace("-----BEGIN CERTIFICATE-----","");
certbody=certbody.Replace("\r\n","");
byte[] certbytes = System.Convert.FromBase64String(certbody);
X509Certificate cert = new X509Certificate(certbytes);
byte[] srcData = Encoding.UTF8.GetBytes(与客户提交的签名匹配的内容);
// 对源二进制进行hash运算。跟签名时使用的要一致。
byte[] hashedData = SHA1.Create().ComputeHash(srcData);
// 获得客户发送来的,需要验证的信息。Convert.FromBase64String对于出现的单字节字符处理会抛出异常,注意捕获。
byte[] signedData = Convert.FromBase64String(客户发送回来的已签名的字符串,Base64格式. 有二进制更好,省得转换);
//用于验证签名的对象
RSAPKCS1SignatureDeformatter rsaSDF = new RSAPKCS1SignatureDeformatter();
rsaSDF.SetKey(cert.PublicKey.Key);//cert为X509Certificate2对象,即公钥对应的证书。
rsaSDF.SetHashAlgorithm("SHA1"); //设定签名时用的hash算法。
bool flag = rsaSDF.VerifySignature(hashedData, signedData); --------------------编程问答-------------------- 顶啊 --------------------编程问答-------------------- 太專業沒用過,幫頂 --------------------编程问答-------------------- X.509没用过,上网查了查,里面嵌含了“签名算法标识符”。
“算法标识符用来指定CA签发证书时所使用的公开密钥算法和HASH算法”
所以LZ仅仅给出RSA,而不给出HASH算法是不能进行认证的。
其实如果不能使用dotnet2.0自带的X509Certificate2,也可以自己写一个认证方法。
请仔细理解9L的朋友的解答。
我对9L的2点补充是:
1、这个HASH算法不一定是SHA1,它是在X.509的“算法标识符”里应该有指定的。
2、第一步“byte[] srcData = Encoding.UTF8.GetBytes(与客户提交的签名匹配的内容); ”
这里的“与客户提交的签名匹配的内容”更具体的指是除去X.509认证头、数字签名之外的源文件内容。
--------------------编程问答-------------------- 我就和文盲看书一样看了半天,晕 --------------------编程问答-------------------- 遇到和楼主一样的问题,谢谢各位回帖者,受益匪浅啊! --------------------编程问答-------------------- gz & xx --------------------编程问答-------------------- 楼主要是解决了,请贴出来哦! --------------------编程问答-------------------- mark --------------------编程问答-------------------- 有用,mask --------------------编程问答-------------------- 有用,mask
补充:.NET技术 , C#