分享
分销 收藏 举报 申诉 / 11
播放页_导航下方通栏广告

类型java数字签名(签名生成-用证书验证签名).doc

  • 上传人:仙人****88
  • 文档编号:12023560
  • 上传时间:2025-08-29
  • 格式:DOC
  • 页数:11
  • 大小:94KB
  • 下载积分:10 金币
  • 播放页_非在线预览资源立即下载上方广告
    配套讲稿:

    如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。

    特殊限制:

    部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。

    关 键  词:
    java 数字签名 签名 生成 证书 验证
    资源描述:
    java数字签名(签名生成,用证书验证签名) java数字签名(签名生成,用证书验证签名) 2008-11-17 17:09 证书(Certificate,也称public-key certificate)是用某种签名算法对某些内容(比如公钥)进行数字签名后得到的、可以用来当成信任关系中介的数字凭证。证书发行机构通过发行证书 告知证书使用者或实体其公钥(public-key)以及其它一些辅助信息。证书在电子商务安全交易中有着广泛的应用,证书发行机构也称 CA(Certificate Authority)。 应用证书 证书在公钥加密应用中的作用是保证公钥在某些可信的机构发布,其在协议SSL、电子交易协议SET等方面有重要的应用。图1显示了一个最简单的证书应用方法:   图1 证书应用方法 证书的应用步骤是: (1) A把自己的公钥PKA送到CA(Certificate Authority); (2) CA用自己的私钥和A的公钥生成A的证书,证书内包括CA的数字签名。签名对象包括需要在证书中说明的内容,比如A的公钥、时间戳、序列号等,为了简化这 里不妨假设证书中只有三项内容:A的公钥PKA、时间戳TIME1、序列号IDA。那么CA发送给A的简单证书凭证可表达 为:CertA=Eca[TIME1,IDA,PKA]; (3) B同样把自己的公钥PKB送到CA; (4) B得到CA发布的证书CertB; (5) A告知B证书CertA; (6) B告知A证书CertB。 A、B各自得到对方证书后,利用从CA得到的公钥(在CA的自签证书中)验证彼此对方的证书是否有效,如果有效,那么就得到了彼此的公钥。利用对方的公钥,可以加密数据,也可以用来验证对方的数字签名。 本文为了方便说明,并没有使用从CA获得的证书,而是通信双方各自产生自签证书,也就是说图1的A和B并没有经过CA,不过前提是A和B之间是互相拥有对方的证书。 证书的内容和意义如表1所示(这里以通用X .509证书格式为例)。 表1 证书内容和意义   证书内容 意义 Version 告诉这个X.509证书是哪个版本的,目前有v1、V2、v3 Serial Number 由证书分发机构设置证书的序列号 Signature Algorithm Identifier 证书采用什么样的签名算法 Issuer Name 证书发行者名,也就是给这个证书签名的机构名 Validity Period 证书有效时间范围 Subject Name 被证书发行机构签名后的公钥拥有者或实体的名字,采用X.500协议,在Internet上的标志是惟一的。例如:CN=Java,OU=Infosec,O=Infosec Lab,C=CN表示一个subject name。 对证书的详细定义及其应用相关的各种协议,这里不加详细说明,详细细节请查看RFC2450、RFC2510、RFC2511、RFC2527、RFC2528、RFC2559、RFC2560、RFC2585、RFC2587等文档。 生成自签证书 个人或机构可以从信任的证书分发机构申请得到证书,比如说,可以从 得到一个属于个人的证书。这里可以利用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哈希算法 摘要。接下来,系统会提示进行一些输入: 输入keystore密码:   abc123 您的名字与姓氏是什么?    [Unknown]:   Li 您的组织单位名称是什么?    [Unknown]:   InfosecLab 您的组织名称是什么?    [Unknown]:   InfosecLab Group 您所在的城市或区域名称是什么?    [Unknown]:   Beijing 您所在的州或省份名称是什么?    [Unknown]:   Beijing 该单位的两字母国家代码是什么    [Unknown]:   CN CN=Li, OU=InfosecLab, O=InfosecLab Group, L=Beijing, ST=Beijing, C=CN 正确吗? [否]:   y 输入<testkeypair>的主密码 (如果和 keystore 密码相同,按回车): 第二步,产生自签证书,输入以下命令: keytool -selfcert -alias testkeypair -dname "CN=Li, OU=InfosecLab, O=InfosecLab Group, L=Beijing, ST=Beijing, C=CN" 输入keystore密码:   abc123 第三步,导出自签证书,由上面两步产生的证书,已经存放在以“testkeypair”为别名的keystore入口了,如果使用其文件,必须导出证书。输入: keytool -export -rfc -alias testkeypair -file mycert.crt   输入keystore密码:   abc123 保存在文件中的认证 <mycert.crt> 这样,就得到了一个自签的证书mycert.crt。注意,选项rfc是把证书输出为RFC1421定义的、用Base64最终编码的格式。 读取证书 Java为安全应用提供了丰富的API,J2SDK1.4 的JSSE (JavaTM Secure Socket Extension) 包括javax.security.certificate包,并且提供对证书的操作方法。而对证书的读操作,只用 java.security.cert. CertificateFactory和java.security.cert.X509Certificate就可以了。下面是读取证书内容的部分代 码: import javax.swing.*; import java.awt.*; import java.awt.event.*; import javax.swing.table.*; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.io.*; public class CARead extends JPanel { private String CA_Name; private String CA_ItemData[][] = new String[9][2]; private String[] columnNames = {"证书字段标记","内容" }; public CARead(String CertName) {    CA_Name=CertName;    /* 三个Panel用来显示证书内容*/    JTabbedPane tabbedPane = new JTabbedPane();    JPanel panelNormal = new JPanel();    tabbedPane.addTab("普通信息", panelNormal);       JPanel panelAll=new JPanel();    panelAll.setLayout(new BorderLayout());    tabbedPane.addTab("所有信息",panelAll);    JPanel panelBase64=new JPanel();    panelBase64.setLayout(new BorderLayout());    tabbedPane.addTab("Base64编码信息",panelBase64);    /* 读取证书常规信息 */    Read_Normal(panelNormal);    /* 读取证书文件字符串表示内容 */    Read_Bin(panelAll);    /* 读取证原始Base64编码形式的证书文件 */    Read_Raw(panelBase64);    tabbedPane.setSelectedIndex(0);    setLayout(new GridLayout(1, 1));    add(tabbedPane); }    /*以下是定义的Read_Normal(),Read_Bin(),Read_Raw()以及main()    这里省略...    */   } 定义证书信息的读取函数如下: private int Read_Normal(JPanel panel){ String Field; try{    CertificateFactory certificate_factory=CertificateFactory.getInstance("X.509");    FileInputStream file_inputstream=new FileInputStream(CA_Name);    X509Certificate x509certificate=(X509Certificate)certificate_factory.generateCertificate (file_inputstream);    Field=x509certificate.getType();    CA_ItemData[0][0]="类型";    CA_ItemData[0][1]=Field;    Field=Integer.toString(x509certificate.getVersion());    CA_ItemData[1][0]="版本";    CA_ItemData[1][1]=Field;    Field=x509certificate.getSubjectDN().getName();    CA_ItemData[2][0]="标题";    CA_ItemData[2][1]=Field;    /* 以下类似,这里省略    Field=x509certificate.getNotBefore().toString();得到开始有效日期    Field=x509certificate. getNotAfter().toString();得到截止日期    Field=x509certificate.getSerialNumber().toString(16);得到序列号    Field=x509certificate.getIssuerDN().getName();得到发行者名    Field=x509certificate.getSigAlgName();得到签名算法    Field=x509certificate.getPublicKey().getAlgorithm();得到公钥算法 */    file_inputstream.close();    final JTable table = new JTable(CA_ItemData, columnNames);    TableColumn tc=null;    tc = table.getColumnModel().getColumn(1);    tc.setPreferredWidth(600);    panel.add(table); }catch(Exception exception){    exception.printStackTrace();    return -1; } return 0; } 如果以字符串形式读取证书,加入下面Read_Bin这个函数。其中CertificateFactory.generateCertificate() 这个函数可以从证书标准编码(RFC1421定义)中解出可读信息。Read_Bin函数代码如下: private int Read_Bin(JPanel panel){ try{    FileInputStream file_inputstream=new FileInputStream(CA_Name);    DataInputStream data_inputstream=new DataInputStream(file_inputstream);    CertificateFactory certificatefactory=CertificateFactory.getInstance("X.509");    byte[] bytes=new byte[data_inputstream.available()];    data_inputstream.readFully(bytes);    ByteArrayInputStream bais=new ByteArrayInputStream(bytes);    JEditorPane Cert_EditorPane;    Cert_EditorPane=new JEditorPane();    while(bais.available()>0){    X509Certificate Cert=(X509Certificate)certificatefactory.generateCertificate(bais);    Cert_EditorPane.setText(Cert_EditorPane.getText()+Cert.toString()); } Cert_EditorPane.disable(); JScrollPane edit_scroll=new JScrollPane(Cert_EditorPane); panel.add(edit_scroll); file_inputstream.close(); data_inputstream.close(); }catch( Exception exception){    exception.printStackTrace();    return -1; } return 0; } 如果要得到原始证书编码后的信息,则可用如下代码: private int Read_Raw(JPanel panel){ try{    JEditorPane Cert_EditorPane=new JEditorPane();    String CertText=null;    File inputFile = new File(CA_Name);    FileReader in = new FileReader(inputFile);    char[] buf=new char[2000];    int len=in.read(buf,0,2000);    for(int i=1;i<len;i++)    {        CertText=CertText+buf[i];    }    in.close();    Cert_EditorPane.setText(CertText);    Cert_EditorPane.disable();    JScrollPane edit_scroll=new JScrollPane(Cert_EditorPane);    panel.add(edit_scroll); }catch( Exception exception){    exception.printStackTrace();    return -1; } return 0; } 最后用这个小程序看一看刚才生成的证书mycert.crt内容,把文件名写入main()中: public static void main(String[] args) { JFrame frame = new JFrame("证书阅读器"); frame.addWindowListener(new WindowAdapter() {    public void windowClosing(WindowEvent e) {System.exit(0);} }); frame.getContentPane().add(new CARead("mycert.crt"),BorderLayout.CENTER); frame.setSize(700, 425); frame.setVisible(true); } 证书mycert.crt的内容显示如图2所示,所有信息和Base64的显示内容,这里不再列举。   图2 证书mycert.crt的内容显示 现在已经读取了证书的一些内容,那么怎样使用证书呢?我们可以假设A和B要共享一个绝密的文件F,B信任并拥有A的 证书,也就是说B拥有A的公钥。那么A通过A和B共知的加密算法(对称密钥算法,比如DES算法)先加密文件F,然后对加密后的F进行签名和散列摘要(比 如MD5算法,目的是保证文件的完整性),然后把F发送到B。B收到文件后,先用A的证书中的公钥验证签名,然后再用通过共知的加密算法解密,就可以得到 原文件了。这里使用的数字签名,可以保证B得到的文件,就是A的,A不能否认其不拥有文件F,因为只有A拥有可以让A的公钥验证其签名的私钥,同时这里使 用DES算法加密,使得文件有保密性。 使用DES算法的加密解密函数类似,这里不对加密算法做进一步讨论,详细请看J2SDK的JSE部分内容,加密签名、解密验证文件结构见图3。 图3 加密签名、解密验证文件结构图 加密函数中的desKeyData存放DES加密密钥,如果要在程序中指定,可以设置为: static byte[] desKeyData = { (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08 }; 加密函数写成: public static void crypt(byte[] cipherText,String outFileName){ try{    DESKeySpec desKeySpec = new DESKeySpec(desKeyData);    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");    SecretKey secretKey = keyFactory.generateSecret(desKeySpec);    Cipher cdes = Cipher.getInstance("DES");    cdes.init(Cipher.ENCRYPT_MODE, secretKey);    byte[] ct = cdes.doFinal(cipherText);    try{     FileOutputStream out=new FileOutputStream(outFileName);     out.write(ct);     out.close();    }catch(IOException e){     e.printStackTrace();    } }catch (Exception e){    e.printStackTrace(); } } 其中ct就是加密后的内容,outFileName保存加密后文件的文件名。把cdes.init(Cipher.ENCRYPT_MODE, secretKey)换成cdes.init(Cipher.DECRYPT_MODE, secretKey)就是解密文件了。 文件加密后就要对文件签名,保证A发送到B的文件不可伪造。下面是用存放在.keystore中的私钥进行签名的函数,签名使用的摘要算法是MD5。其中 sigText是被签名内容的输入数组,outFileName是保存签名后输出文件的名称,KeyPassword是读取Keystore使用的密 码,KeyStorePath是存放.keystore文件的路径,函数代码如下: public static void sig(byte[] sigText, String outFileName,String KeyPassword,String KeyStorePath){ char[] kpass; int i; 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<KeyPassword.length();i++)     kpass[i]=KeyPassword.charAt(i);    ks.load(ksbufin, kpass);    PrivateKey priv = (PrivateKey) ks.getKey(KeystoreAlias,kpass );    Signature rsa=Signature.getInstance("MD5withRSA");      rsa.initSign(priv);    rsa.update(sigText);    byte[] sig=rsa.sign();    System.out.println("sig is done");    try{     FileOutputStream out=new FileOutputStream(outFileName);     out.write(sig);     out.close();    }catch(IOException e){     e.printStackTrace();    }     }catch(Exception e){    e.printStackTrace(); } } 验证签名需要存放签名文件和被签名的文件以及证书,其中,updateData存放被签名文件的内容,sigedText存放得到的签名内容,CertName是证书名。验证签名代码如下: public static void veriSig(byte[] updateData, byte[] sigedText){      try{            CertificateFactory certificatefactory=CertificateFactory.getInstance("X.509"); FileInputStream fin=new FileInputStream(CertName); 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();             } } 可以用keytool产生两个自签的签名证书,或者到某个CA去申请两个证书。用Java编写加密和验证程序,上述例子只是一个非常简单的证书应用,实际协议对证书的使用(比如SSL)要比这个复杂多了。
    展开阅读全文
    提示  咨信网温馨提示:
    1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
    2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
    3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
    4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前可先查看【教您几个在下载文档中可以更好的避免被坑】。
    5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
    6、文档遇到问题,请及时联系平台进行协调解决,联系【微信客服】、【QQ客服】,若有其他问题请点击或扫码反馈【服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【版权申诉】”,意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:0574-28810668;投诉电话:18658249818。

    开通VIP折扣优惠下载文档

    自信AI创作助手
    关于本文
    本文标题:java数字签名(签名生成-用证书验证签名).doc
    链接地址:https://www.zixin.com.cn/doc/12023560.html
    页脚通栏广告

    Copyright ©2010-2025   All Rights Reserved  宁波自信网络信息技术有限公司 版权所有   |  客服电话:0574-28810668    微信客服:咨信网客服    投诉电话:18658249818   

    违法和不良信息举报邮箱:help@zixin.com.cn    文档合作和网站合作邮箱:fuwu@zixin.com.cn    意见反馈和侵权处理邮箱:1219186828@qq.com   | 证照中心

    12321jubao.png12321网络举报中心 电话:010-12321  jubao.png中国互联网举报中心 电话:12377   gongan.png浙公网安备33021202000488号  icp.png浙ICP备2021020529号-1 浙B2-20240490   


    关注我们 :微信公众号  抖音  微博  LOFTER               

    自信网络  |  ZixinNetwork