当前位置:编程学习 > C#/ASP.NET >>

数字证书验证的问题,高分!

是用usbKey从客户端数字签名后,再把签名后的信息返回到服务器中,再用服务器的数字证书来验证
问题是怎样验证?
是X.509,用的算法应该是rsa,怎样利用证书的公钥来验证签名后的信息呢?
拜托了 --------------------编程问答-------------------- 帮顶up --------------------编程问答-------------------- 多谢上楼了
自己再UP --------------------编程问答-------------------- 你这问题太专业,估计会的人不多!
我也只能帮你鼎了! --------------------编程问答-------------------- 有意思。先mark --------------------编程问答-------------------- 顶
没使用过楼主说的算法! --------------------编程问答-------------------- 试一下下面的代码
using System;
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;
            }
        }
    }
}
  --------------------编程问答-------------------- 多谢cocosoft甴曱!
你提供的例子好像只能在.net2.0中的,没有没.net1.1的 --------------------编程问答-------------------- 在.NET 1.1里面并不支持 X509Store及X509Certificate2,其中,X509Certificate2可使用X509Certificate来代替。不能使用X509Store,那么你可以使用如下代码来实现读取:

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);
--------------------编程问答-------------------- // 建立需要校验的源,可自行选择编码格式,我的用的UTF8编码。
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#
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,