数字签名使用手册
一.概述
原理及特点
每个人都有一对「钥匙」(数字身份),其中一个只有她/他本人知道(密钥),另一个公开的(公钥)。签名的时候用私钥,验证签名的时候用公钥。又因为任何人都可以落款申称她/他就是你,因此公钥必须向接受者信任的人(身份认证机构)来注册。注册后身份认证机构给你发一数字证书。对文件签名后,你把此数字证书连同文件及签名一起发给接受者,接受者向身份认证机构求证是否真地是用你的密钥签发的文件。
在通讯中使用数字签名一般基于以下原因:
鉴权:
公钥加密系统允许任何人在发送信息时使用私钥进行加密,数字签名能够让信息接收者利用发送者的公钥确认发送者的身份。当然,接收者不可能百分之百确信发送者的真实身份,而只能在密码系统未被破译的情况下才有理由确信。
鉴权的重要性在财务数据上表现得尤为突出。举个例子,假设一家银行将指令由它的分行传输到它的管理系统,指令的格式是(a,b),其中a是账户的账号,而b是账户的现有金额。这时一位远程客户可以先存入100元,观察传输的结果,然后接二连三的发送格式为(a,b)的指令。这种方法被称作重放攻击。
完整性:
传输数据的双方都总希望确认消息未在传输的过程中被修改。加密使得第三方想要读取数据十分困难,然而第三方仍然能采取可行的方法在传输的过程中修改数据。一个通俗
的例子就是同形攻击:回想一下,还是上面的那家银行从它的分行向它的管理系统发送格式为(a,b)的指令,其中a是账号,而b是账户中的金额。一个远程客户可以先存100元,然后拦截传输结果,再传输(a,b3),这样他就立刻变成百万富翁了。
不可否认性:
在密文背景下,抵赖这个词指的是不承认与消息有关的举动(即声称消息来自第三方)。消息的接收方可以通过数字签名来防止所有后续的抵赖行为,因为接收方可以出示签名给别人看来证明信息的来源。
二.平台实现
渠道请求平台:
渠道请求平台数据需要签名,然后综合接入平台需要使用渠道提供的公钥进行解密,确认
平台推送交易结果
综合接入平台会对推送的交易结果进行签名,推送给各个渠道,各个渠道在使用综合接入平台提供的公钥进行解密确认。
三.数字签名的生成
生成自签证书:
个人或机构可以从信任的证书分发机构申请得到证书,比如说,可以从http://ca.pku.edu.cn 得到一个属于个人的证书。这里可以利用J2SDK的安全工具keytool手工产生自签证书,所谓自签证书是指证书中的“Subject Name”和“Issuer Name”相同的证书。
下面产生一个自签证书。安装完J2SDK(这里用的是J2SDK1.4)后,在J2SDK安装目录的bin目录下,有一个keytool的可执行程序。利用keytool产生自签证书的步骤如下:
第一步,用-genkey命令选项,产生公私密钥对。在控制台界面输入:keytool -genkey -alias testkeypair -keyalg RSA -keysize 1024 -sigalg MD5withRSA。这里的-alias表示使用这对公私密钥产生新的keystore入口的别名(keystore是用来存放管理密钥对和证书链的,缺省位置是在使用者主目录下,以.keystore为名的隐藏文件,当然也可指定某个路径存放.keystore文件);-keyalg是产生公私钥对所用的算法,这里是RSA;-keysize定义密钥的长度;-sigalg是签名算法,选择MD5withRSA,即用RSA签名,然后用MD5哈希算法摘要。接下来,系统会提示进行一些输入:
第二步,导出自签证书,由上面两步产生的证书,已经存放在以“testkeypair”为别名的keystore入口了,如果使用其文件,必须导出证书。输入
四.Java 数字签名,验证例子
package com.platform.digit;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
public class TestDigit {
/**
*
* @param sigText
* @param KeyPassword keystore密码
* @param KeyStorePath 公私密钥对,keystore是用来存放管理密钥对和证书链的
* @param alias 表示使用这对公私密钥产生新的keystore入口的别名
* @return
*/
public static String sig(byte[] sigText, String
KeyPassword,String KeyStorePath,String alias){
char[] kpass;
int i;
String encodeStr=null;
try{
KeyStore ks = KeyStore.getInstance(\"JKS\");
FileInputStream ksfis = new FileInputStream(KeyStorePath);
BufferedInputStream ksbufin = new BufferedInputStream(ksfis);
kpass=new char[KeyPassword.length()];
for(i=0;i ks.load(ksbufin, kpass); PrivateKey priv = (PrivateKey) ks.getKey(alias,kpass ); Signature rsa=Signature.getInstance(\"MD5withRSA\"); rsa.initSign(priv); rsa.update(sigText); byte[] sig=rsa.sign(); sun.misc.BASEEncoder base = new sun.misc.BASEEncoder(); encodeStr=base.encode(sig); System.out.println(\"sig is done \"+encodeStr); }catch(Exception e){ e.printStackTrace(); } return encodeStr; } /** * * @param updateData * @param sigedText */ public static void veriSig(byte[] updateData, byte[] sigedText){ try{ CertificateFactory certificatefactory=CertificateFactory.getInstance(\"X.509\"); FileInputStream fin=new FileInputStream(\"e://14_public.cer\");//公钥路径 X509Certificate certificate=(X509Certificate)certificatefactory.generateCertificate(fin); PublicKey pub = certificate.getPublicKey(); Signature rsa=Signature.getInstance(\"MD5withRSA\"); rsa.initVerify(pub); rsa.update(updateData); boolean verifies=rsa.verify(sigedText); System.out.println(\"verified \"+verifies); if(verifies){ System.out.println(\"Verify is done!\"); }else{ System.out.println(\"verify is not successful\"); } }catch(Exception e){ e.printStackTrace(); } } public static void createKeyPairs() throws Exception { } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub // String encodeStr = \"fHvkfVPzuZgE+0XMH6qD1D9FgNrUL3XL4x8ZbOOoipLd03VvF06ZLZ4h/vFkeB4iF0Jn1h8+S5OV211LFlXJrw08DqmhH1Pp4J4SOaVgs6K0z/adRVUj5jfDoJOG0+mE9LdhIs9g62TUzVKtFpMKCratJZjdMuH3tbgzNqKXzRE=\"; // String encodeStr=\"I2Q5IKEL5HaF/N4tVBbO+GaOkPShnblKP70HjoLhglTbtXBSx69fW/xWj27BEBloCkTlXOPwYN+vEdk+UvQfge90ACkXGtjG75o5Knx2fopgHEHcsMhbIB4tjbyvKyaQcJiFX4FougMvyhjVWljIpU8A6KzHMJRRFFE7jFWTTUQ=\"; String sss2=\"000transcode=\\\"000\\\" version=\\\"1.0\\\" partnerid=\\\"14\\\" encoding=\\\"UTF-8\\\"?>\\n String siger=null; siger = TestDigit.sig(sss2.getBytes(), \"111111\", \"e://14_private\",\"500wan\"); byte[] sigedText = null; sun.misc.BASEDecoder base = new sun.misc.BASEDecoder(); try { sigedText = base.decodeBuffer(siger); } catch (IOException e) { e.printStackTrace(); } // System.out.println(encodeStr); System.out.println(\"siger------\"+siger); TestDigit.veriSig(sss2.getBytes(), sigedText); } } 因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- azee.cn 版权所有 赣ICP备2024042794号-5
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务