.net连接java web service 公钥私钥证书验签

最近和银行做接口,前前后后断断续续做了3个月,终于大功告成。

在此期间,查了不少资料,发现网上关于.net如何验签的文章不多,现在把我的经验贡献给大家,希望有点用处。其中一些很容易在网上查到的内容我就不一一说明了,不懂得朋友可以自行学习。本文写的比较简单,请高手指点。

项目说明:

银行方:java的web service接口

本方:.net平台

开发工具:vs2008

一、证书

首先我们手里有两个文件,私钥和公钥。私钥一般是xx.pfx,公钥一般是xx.cer。公钥由银行提供,私钥由本方按照文档在银行网站生成。在本机导入证书。

二、连通过程

因为银行没有.net的说明文档,所以一切都靠自己摸索。

首先在vs的工程中添加web reference,输入银行提供的wsdl路径,vs自动生成接口框架类(Payment)。看了一下自动生成的类,里面是银行web service的接口。

第二步建立调用接口的代码

    private CookieContainer cookies;

    private static Payment pss = new Payment();

    public Service()
    {

//加入密钥
        //pss.ClientCertificates.Add(X509Certificate.CreateFromCertFile(System.AppDomain.CurrentDomain.BaseDirectory + "App_Data\\certificate\\new.cer"));
        pss.ClientCertificates.Add(new X509Certificate2(System.AppDomain.CurrentDomain.BaseDirectory + "App_Data\\certificate\\private.pfx", ""));

        pss.Url = "https://pay.bank.com/Payment/services/PaymentServices";                  
        ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);

  //局域网内调试
        if (Environment.UserDomainName.Equals("x"))
        {
            WebProxy myProxy = new WebProxy("129.1.0.0:8080", false);
            myProxy.Credentials = new NetworkCredential("xxx", "xxx", "xxx");
            pss.Proxy = myProxy;
        }
    
        cookies = new CookieContainer();
        pss.CookieContainer = cookies;
        pss.AllowAutoRedirect = true;
       
    }

        public static string Login()
    {
        try
        {
            return pss.login(getLogin());
        }
        catch (Exception e)
        {
            Log(e.StackTrace);
            Log(e.Message);
            return "";
        }
    }

  

//网站到银行的登录接口 

    private static String getLogin()
    {
        string now = DateTime.Now.ToString("yyyyMMddhhmmss");

        StringBuilder sb = new StringBuilder();
        sb.Append("<?xml version=\"1.0\" encoding=\"GBK\"?>");
        sb.Append("<message method=\"login\" type=\"request\">");
        sb.Append("<infoType>0800</infoType>");
        sb.Append("<posTime>").Append(now).Append("</posTime>");
        sb.Append("<posID>000001</posID>");
        sb.Append("<transTime>").Append(now.Substring(8)).Append("</transTime>");
        sb.Append("<transDate>").Append(now.Substring(0, 8)).Append("</transDate>");
        sb.Append("<retCode></retCode>");
        sb.Append("<terminalID></terminalID>");
        sb.Append("<merchantID>").Append(merId).Append("</merchantID>");
        sb.Append("<merchantName>www.jyoule.com交友乐</merchantName>");
        sb.Append("<password>xxx</password>");
        sb.Append("<commentRes></commentRes>");
        sb.Append("<resParam></resParam>");
        sb.Append("<reserved></reserved>");
        sb.Append("</message>");
        Log(sb.ToString());
        return sb.ToString();
    }

这个时候发生了一个问题,不论如何修改都无法连接到对方的web service上,IE是可以连接上对方的web service网页的。查了很多网站,也没有得到结果,后来偶尔加入了pss.Url="https://pay.bank.com/Payment/services/PaymentServices"; ,居然连接上了。查看了一下框架类,里面明明有Url的值。这个问题一直没找到原因。

注意如果是局域网内调试,需要加入proxy。

另外根据银行的需要,你可以选择是使用公钥X509Certificate来登录,还是试用私钥X509Certificate2来登录。这里使用了私钥。

三、验签

验签的代码是网上找来的,需要注意的是对方可能是公钥加密,我们需要用私钥解密,也可能对方是私钥加密,我们需要公钥解密。我就碰到对方测试环境和生产环境做法不一样,导致花了好几天才找到问题。

        /// <summary>
        /// 引用证书非对称加/解密RSA-私钥验签【OriginalString:原文(有中文用utf-8编码的字节);SignatureString:签名字符;prikey_path:证书路径;CertificatePW:证书密码;SignType:签名摘要类型(1:MD5,2:SHA1)】
        /// </summary>
        public static bool CerRSAVerifySignatureByPrivate(byte[] OriginalString, byte[] SignatureString, string prikey_path, string CertificatePW, int SignType)
        {
            X509Certificate2 x509_Cer1 = new X509Certificate2(prikey_path, CertificatePW);
            RSACryptoServiceProvider rsapub = (RSACryptoServiceProvider)x509_Cer1.PrivateKey;
            rsapub.ImportCspBlob(rsapub.ExportCspBlob(false));
            RSAPKCS1SignatureDeformatter f = new RSAPKCS1SignatureDeformatter(rsapub);
            byte[] HashData;
            switch (SignType)
            {
                case 1:
                    f.SetHashAlgorithm("MD5");//摘要算法MD5
                    MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
                    HashData = md5.ComputeHash(OriginalString);
                    break;
                default:
                    f.SetHashAlgorithm("SHA1");//摘要算法SHA1
                    SHA1CryptoServiceProvider sha = new SHA1CryptoServiceProvider();
                    HashData = sha.ComputeHash(OriginalString);
                    break;
            }
            if (f.VerifySignature(HashData, SignatureString))
            {
                return true;
            }
            else
            {
                return false;
            }
        }    

 

        /// <summary>
        /// 引用证书非对称加/解密RSA-公钥验签【OriginalString:原文(有中文用utf-8编码的字节);SignatureString:签名字符;pubkey_path:证书路径;CertificatePW:证书密码;SignType:签名摘要类型(1:MD5,2:SHA1)】
        /// </summary>
        public static bool CerRSAVerifySignature(byte[] OriginalString, byte[] SignatureString, string pubkey_path, string CertificatePW, int SignType)
        {
            X509Certificate2 x509_Cer1 = new X509Certificate2(pubkey_path, CertificatePW);
            RSACryptoServiceProvider rsapub = (RSACryptoServiceProvider)x509_Cer1.PublicKey.Key;
            rsapub.ImportCspBlob(rsapub.ExportCspBlob(false));
            RSAPKCS1SignatureDeformatter f = new RSAPKCS1SignatureDeformatter(rsapub);
            byte[] HashData;
            switch (SignType)
            {
                case 1:
                    f.SetHashAlgorithm("MD5");//摘要算法MD5
                    MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
                    HashData = md5.ComputeHash(OriginalString);
                    break;
                default:
                    f.SetHashAlgorithm("SHA1");//摘要算法SHA1
                    SHA1CryptoServiceProvider sha = new SHA1CryptoServiceProvider();
                    HashData = sha.ComputeHash(OriginalString);
                    break;
            }
            if (f.VerifySignature(HashData, SignatureString))
            {
                return true;
            }
            else
            {
                return false;
            }

我是用SHA1算法,注意byte的转换

CerRsa.CerRSAVerifySignature(Encoding.UTF8.GetBytes(orgData.ToString()), Convert.FromBase64String(payment.Signature), pubkey_path, "", 2)

转载于:https://www.cnblogs.com/jyoule/archive/2010/09/09/1822538.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值