Java加解密密和数字签名

1. 消息摘要
[java]  view plain  copy
  1. String beforeDegist = "asdf";    
  2. System.out.println("摘要前:"+beforeDegist);      
  3.     
  4. //初始信息要转换成字节流的形式    
  5. byte[] plainText = beforeDegist.getBytes("UTF8");    
  6.   
  7. //使用getInstance("算法")来获得消息摘要,这里使用SHA-1的160位算法或者MD5算法  
  8. geDigest messageDigest = MessageDigest.getInstance("SHA-1");    
  9. MessageDigest messageDigest = MessageDigest.getInstance("MD5");    
  10.     
  11. System.out.println("/n" + messageDigest.getProvider().getInfo());    
  12.     
  13. //开始使用算法    
  14. messageDigest.update(plainText);    
  15.     
  16. //输出算法运算结果    
  17. String afterDegist = new String(messageDigest.digest(),"UTF8");    
  18. System.out.println("摘要后:"+afterDegist);   
              
2. 私钥加密
[java]  view plain  copy
  1.   /**  
  2.    * 此例子是对一个字符串信息,用一个私钥(key)加密,然后在用该私钥解密,验证是否一致  
  3.    * 私钥加密,是对称加密  
  4.    * 使用对称算法。比如:A用一个密钥对一个文件加密,而B读取这个文件的话,则需要和A一样的密钥,双方共享一  
  5.    * 个私钥(而在web环境下,私钥在传递时容易被侦听)  
  6.    *   
  7.    * 附:主要对称算法有:DES(实际密钥只用到56 位)  
  8.    * AES(支持三种密钥长度:128、192、256位),通常首先128位,其他的还有DESede等  
  9.    */   
  10. <span style="white-space: pre; ">   </span>String before = "asdf";           
  11.         byte[] plainText = before.getBytes("UTF8");    
  12.             
  13.         // STEP 1.                 
[java]  view plain  copy
  1. System.out.println("Start generate AES key.");    
  2.   
  3. //得到一个使用AES算法的KeyGenerator的实例    
  4. KeyGenerator keyGen = KeyGenerator.getInstance("AES");    
  5.   
  6. //定义密钥长度128位    
  7. keyGen.init(128);    
  8.   
  9. //通过KeyGenerator产生一个key(密钥算法刚才已定义,为AES)    
  10. Key key = keyGen.generateKey();    
  11.   
  12. System.out.println("Finish generating AES key="+key);    

        //STEP 2.       
[java]  view plain  copy
  1.        //获得一个私钥加密类Cipher,定义Cipher的基本信息:ECB是加密方式,PKCS5Padding是填充方法    
  2.        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");    
  3. //System.out.println("/n" + cipher.getProvider().getInfo());    
         
        //STEP 3.      
[java]  view plain  copy
  1. // 使用私钥加密    
  2. System.out.println("/n用私钥加密...");    
  3. // 把刚才生成的key当作参数,初始化使用刚才获得的私钥加密类,Cipher.ENCRYPT_MODE意思是加密    
  4. cipher.init(Cipher.ENCRYPT_MODE, key);    
  5.     
  6. //私钥加密类Cipher进行加密,加密后返回一个字节流byte[]    
  7. byte[] cipherText = cipher.doFinal(plainText);    
  8.     
  9. //以UTF8格式把字节流转化为String    
  10. String after1 = new String(cipherText, "UTF8");    
  11. System.out.println("用私钥加密完成:"+after1);    
          
        // STEP 4.     
[java]  view plain  copy
  1. //使用私钥对刚才加密的信息进行解密,看看是否一致,Cipher.DECRYPT_MODE意思是解密钥    
  2. System.out.println("/n用私钥解密...");    
  3. cipher.init(Cipher.DECRYPT_MODE, key);    
  4.     
  5. //对刚才私钥加密的字节流进行解密,解密后返回一个字节流byte[]    
  6. byte[] newPlainText = cipher.doFinal(cipherText);    
  7.     
  8. String after2 = new String(newPlainText, "UTF8");    
  9. System.out.println("用私钥解密完成:"+after2);    

3. 公钥加密
[java]  view plain  copy
  1.        String before = "asdf";           
  2.        byte[] plainText = before.getBytes("UTF8");    
  3.            
  4.        //产生一个RSA密钥生成器KeyPairGenerator(顾名思义:一对钥匙生成器)    
  5.        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");    
  6.   
  7.   
  8.        //定义密钥长度1024位    
  9.        keyGen.initialize(1024);    
  10.   
  11.   
  12.        //通过KeyPairGenerator产生密钥,注意:这里的key是一对钥匙!!    
  13.        KeyPair key = keyGen.generateKeyPair();    
  14.   
  15.        //获得一个RSA的Cipher类,使用公钥加密    
  16.        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");    
  17. //System.out.println("/n" + cipher.getProvider().getInfo());    
  18.   
  19.        System.out.println("/n用公钥加密...");    
  20.   
  21.   
  22.        //Cipher.ENCRYPT_MODE意思是加密,从一对钥匙中得到公钥 key.getPublic()    
  23.        cipher.init(Cipher.ENCRYPT_MODE, key.getPublic());    
  24.   
  25.   
  26.        //用公钥进行加密,返回一个字节流    
  27.        byte[] cipherText = cipher.doFinal(plainText);    
  28.   
  29.   
  30.        //以UTF8格式把字节流转化为String    
  31.        String after1 = new String(cipherText, "UTF8");    
  32.   
  33.   
  34.        System.out.println("用公钥加密完成:"+after1);    
  35.   
  36.            
  37.        //使用私钥解密    
  38.        System.out.println("/n用私钥解密...");    
  39.   
  40.   
  41.        //Cipher.DECRYPT_MODE意思是解密模式,从一对钥匙中得到私钥 key.getPrivate()    
  42.        cipher.init(Cipher.DECRYPT_MODE, key.getPrivate());    
  43.   
  44.   
  45.        //用私钥进行解密,返回一个字节流    
  46.        byte[] newPlainText = cipher.doFinal(cipherText);    
  47.   
  48.        String after2 = new String(newPlainText, "UTF8");    
  49.        System.out.println("用私钥解密完成:"+after2);   

4. 数字签名
[java]  view plain  copy
  1. /**  
  2.   * 此例子是数字签名的例子,使用RSA私钥对消息摘要(这里指的是原始数据)进行签名,然后使用公钥验证签名  
  3.   *   
  4.   * A通过使用B的公钥加密数据后发给B,B利用B的私钥解密就得到了需要的数据(进过B公钥加密的数据只有B的私钥能够  
  5.   * 解开,C没有B的私钥,所以C解不开,但C可以使用B的公钥加密一份数据发给B,这样一来,问题来了,B收到的数据到  
  6.   * 底是A发过来的还是C发过来的呢)  
  7.   * 由于私钥是唯一的,那么A就可以利用A自己的私钥进行加密,然后B再利用A的公钥来解密,就可以确定:一定是A的消  
  8.   * 息,数字签名的原理就基于此  
  9.   *   
  10.   * 总结:A想将目标数据传给B,此时A需要准备1和2两部分  
  11.   * 1:A使用B的公钥将原始信息加密,以起到保密作用(只有B的私钥能解开,其他人使用其他钥匙都解不开,当然就保密咯)  
  12.   * 2:A使用A的私钥将原始信息的摘要进行签名,以起到接收方B确定是A发过来的作用(A用A的私钥对目标数据的摘要进行签  
  13.   * 名,然后传给B,同时,C用C的私钥对任意信息进行签名也传给B,B想接受的是A的数据(比如说一个转帐请求),于是B  
  14.   * 就通过A的公钥对接受到的两个信息进行解密,解开的就是A(A的公钥能且只能解开A的私钥加密的数据))  
  15.   */   
  16.  String before = "asdf";    
  17.  byte[] plainText = before.getBytes("UTF8");    
  18.   
  19.  //形成RSA公钥对    
  20.  KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");    
  21.  keyGen.initialize(1024);    
  22.  KeyPair key = keyGen.generateKeyPair();    
  23.   
  24.  //使用私钥签名**********************************************************    
  25.  Signature sig = Signature.getInstance("SHA1WithRSA");    
  26.  sig.initSign(key.getPrivate());//sig对象得到私钥    
  27.   
  28.   
  29.  //签名对象得到原始数据    
  30.  sig.update(plainText);//sig对象得到原始数据(现实中用的是原始数据的摘要,摘要的是单向的,即摘要算法后无法解密)    
  31.  byte[] signature = sig.sign();//sig对象用私钥对原始数据进行签名,签名后得到签名signature    
  32. em.out.println(sig.getProvider().getInfo());    
  33.   
  34.   
  35.  String after1 = new String(signature, "UTF8");    
  36.  System.out.println("/n用私钥签名后:"+after1);    
  37.   
  38.  //使用公钥验证    
  39.  sig.initVerify(key.getPublic());//sig对象得到公钥   
  40.   
  41.   
  42.  //签名对象得到原始信息   
  43.  sig.update(plainText);//sig对象得到原始数据(现实中是摘要)    
  44.  try {    
  45.      if (sig.verify(signature)) {//sig对象用公钥解密签名signature得到原始数据(即摘要),一致则true    
  46.          System.out.println("签名验证正确!!"+new String(plainText, "UTF8"));    
  47.      } else {    
  48.          System.out.println("签名验证失败!!");    
  49.      }    
  50.  } catch (SignatureException e) {    
  51.      System.out.println("签名验证失败!!");    
  52.  }    

  
5. 数字证书  
[java]  view plain  copy
  1. /**  
  2.   * 此例是对“数字证书”文件的操作  
  3.    * java平台(在机器上安装jdk)为你提供了密钥库(证书库),cmd下提供了keytool命令就可以创建证书库  
  4.    *   
  5.    * 在运行此例前:  
  6.    * 在c盘目录下创建一个证书,指定证书库为BocsoftKeyLib,创建别名为TestCertification的一条证书,它指定用   
  7.    * RSA 算法生成,且指定密钥长度为1024,证书有效期为1年  
  8.    * 导出证书文件为TC.cer已存于本地磁盘C:/  
  9.    * 密码是qazzaq 
  10.    */   
  11.   try {    
  12.         //前提:将证书库中的一条证书导出到证书文件(我写的例子里证书文件叫TC.cer)    
  13.         //从证书文件TC.cer里读取证书信息    
  14.         CertificateFactory cf = CertificateFactory.getInstance("X.509");   
  15.   
  16.   
  17.         FileInputStream in = new FileInputStream("C:/TC.cer");   
  18.   
  19.   
  20.         //将文件以文件流的形式读入证书类Certificate中   
  21.         Certificate c = cf.generateCertificate(in);   
  22.         System.err.println("转换成String后的证书信息:"+c.toString());*/   
  23.           
  24.         //或者不用上面代码的方法,直接从证书库中读取证书信息,和上面的结果一摸一样    
  25.         String pass="qazzaq";       
  26.         FileInputStream in2=new FileInputStream("C:/BocsoftKeyLib");       
  27.   
  28.   
  29.         KeyStore ks=KeyStore.getInstance("JKS");       
  30.         ks.load(in2,pass.toCharArray());    
  31.         String alias = "TestCertification"//alias为条目的别名    
  32.         Certificate c=ks.getCertificate(alias);    
  33.         System.err.println("转换成String后的证书信息:"+c.toString());    
  34.           
  35.         //获取获取X509Certificate类型的对象,这是证书类获取Certificate的子类,实现了更多方法    
  36.         X509Certificate t=(X509Certificate)c;    
  37.         //从信息中提取需要信息    
  38.         System.out.println("版本号:"+t.getVersion());       
  39.         System.out.println("序列号:"+t.getSerialNumber().toString(16));       
  40.         System.out.println("主体名:"+t.getSubjectDN());       
  41.         System.out.println("签发者:"+t.getIssuerDN());       
  42.         System.out.println("有效期:"+t.getNotBefore());       
  43.         System.out.println("签名算法:"+t.getSigAlgName());   
  44.   
  45.   
  46.         byte [] sig=t.getSignature();//签名值    
  47.         PublicKey pk = t.getPublicKey();     
  48.         byte [] pkenc=pk.getEncoded();       
  49.         System.out.println("公钥:");       
  50.         for(int i=0;i<pkenc.length;i++){    
  51.             System.out.print(pkenc[i]+",");       
  52.         }    
  53.         System.err.println();  
  54.             
  55.         //证书的日期有效性检查,颁发的证书都有一个有效性的日期区间    
  56.         Date TimeNow=new Date();          
  57.         t.checkValidity(TimeNow);       
  58.         System.out.println("证书的日期有效性检查:有效的证书日期!");  
  59.             
  60.         //验证证书签名的有效性,通过数字证书认证中心(CA)机构颁布给客户的CA证书,比如:caroot.crt文件    
  61.         //我手里没有CA颁给我的证书,所以下面代码执行不了    
  62.         /*FileInputStream in3=new FileInputStream("caroot.crt");     
  63.         //获取CA证书  
  64.         Certificate cac = cf.generateCertificate(in3); 
  65.  
  66.  
  67.         //获取CA的公钥     
  68.         PublicKey pbk=cac.getPublicKey();     
  69.         //c为本地证书,也就是待检验的证书,用CA的公钥校验数字证书c的有效性  
  70.         c.verify(pbk);               
  71.     } catch(CertificateExpiredException e){//证书的日期有效性检查:过期      
  72.         System.out.println("证书的日期有效性检查:过期");         
  73.     } catch(CertificateNotYetValidException e){ //证书的日期有效性检查:尚未生效      
  74.         System.out.println("证书的日期有效性检查:尚未生效");      
  75.     } catch (CertificateException ce) {   
  76.         ce.printStackTrace();   
  77.     } catch (FileNotFoundException fe) {   
  78.         fe.printStackTrace();   
  79.     } /*catch (IOException ioe){  
  80.           
  81.     } catch (KeyStoreException kse){  
  82.           
  83.     }*/ catch (Exception e){    
  84.         e.printStackTrace();    
  85.     }   
  86. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值