前提铺垫: 本机上构造两个数字证书用作测试,一个 Server 端 与一个Client 端
使用java keytool 生成自签名证书。

过程如下:


参数如下: 
-genkeypair 生成密钥对
-keyalg 指定密钥算法
-keysize 指定密钥长度
-sigalg 指定签名算法
-validity 证书有效期
-alias 别名
-keystore 密钥库存储位置
注:本文目的不在于生成及导出密钥库证书,故不做详细说明
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
生成并导出获得2份证书: JumpFly.cer   JumpFly2.cer   

单程序上模拟服务端与客户端利用证书进行加解密交换信息-------------------------

定义密钥库相关信息:(模拟中两端存于同一密钥库下,实际上应该是双方自己的独立密钥库)

        private static String password = "123456";
private static String alias = "www.JumpFly.org";
private static String Calias = "www.JumpFly2.org";
private static String certificatePath = "D:/FileBox/CerBox/JumpFly.cer";
private static  String CcertificatePath = "D:/FileBox/CerBox/JumpFly2.cer";
private static String keyStorePath = "C:/Windows/System32/JumpFly.keystore";

定义文件路径:

String FilePath="D:\\FileBox\\JAVA3D.zip"; //原始待加密文件路径
String EnFilePath="D:\\FileBox\\EnJAVA3D.zip";//加密后文件路径
String DeFilePath="D:\\FileBox\\DeJAVA3D.zip";//解密后文件路径

文件摘要使用Commons Codec下的DigestUtils类进行摘要处理(可自行查阅Commons Codec相关内容)

由于证书中无秘密密钥(即对称密钥) 所以需要一方生成 然后加密通知另一方获得对称密钥

具体实现如下:

public static void main(String[] args) throws Exception{String md5Hex;String FilePath="D:\\FileBox\\JAVA3D.zip";String EnFilePath="D:\\FileBox\\EnJAVA3D.zip";String DeFilePath="D:\\FileBox\\DeJAVA3D.zip";//生成摘要FileInputStream fileIn=new FileInputStream(FilePath);md5Hex = DigestUtils.md5Hex(fileIn);System.out.println("文件摘要:"+md5Hex);//产生签名--JumpFly的私钥byte[] sign = CertificateCoder.sign(md5Hex.getBytes(), keyStorePath, alias, password);System.err.println("数字签名:\n" + Hex.encodeHexString(sign));//文件加密byte[] Key=AESCoder.initKey();//二进制对称密钥keyAESCoder.encryptFile(FilePath, EnFilePath, Key);//对称密钥加密--用JumpFly2的公钥byte[] EnKey=CertificateCoder.encryptByPublicKey(Key, CcertificatePath);System.out.println("以上是JumpFly端加密文件发送.....sign、Key、EnFile、EnKey");//对称密钥解密--用JumpFly2的私钥byte[] DeKey=CertificateCoder.decryptByPrivateKey(EnKey, keyStorePath, Calias, password);//文件解密AESCoder.decryptFile(EnFilePath, DeFilePath, DeKey);//验证签名--用JumpFly证书公钥FileInputStream fileIn2=new FileInputStream(DeFilePath);String md5Hex2 = DigestUtils.md5Hex(fileIn2);boolean flag=CertificateCoder.verify(md5Hex2.getBytes(), sign, certificatePath);System.out.println("文件摘要:"+md5Hex2+"\t 验证签名:"+flag);System.out.println("以上是JumpFly2端接收文件解密.....");//生成摘要String msString="这是JumpFly2端发送的消息";String sha1Hex=DigestUtils.sha1Hex(msString.getBytes());System.out.println("消息内容:"+msString+"\t 消息摘要:"+sha1Hex);//产生签名--JumpFly2的私钥byte[] sign2 = CertificateCoder.sign(sha1Hex.getBytes(), keyStorePath, Calias, password);System.err.println("数字签名:\n" + Hex.encodeHexString(sign2));//消息加密byte[] EnMsg=AESCoder.encrypt(msString.getBytes(), DeKey);//对称密钥加密--用JumpFly的证书公钥byte[] EnKey2=CertificateCoder.encryptByPublicKey(DeKey, certificatePath);System.out.println("以上是JumpFly2端加密消息发送.....sign2、EnMsg、EnKey2");//对称密钥解密--用JumpFly的私钥byte[] DeKey2=CertificateCoder.decryptByPrivateKey(EnKey2, keyStorePath, alias, password);//消息解密byte[] DeMsg=AESCoder.decrypt(EnMsg, DeKey2);String msgString=new String(DeMsg);//签名验证--用JumpFly2证书公钥String sha1Hex2 = DigestUtils.sha1Hex(DeMsg);boolean flag2=CertificateCoder.verify(sha1Hex2.getBytes(), sign2, CcertificatePath);System.out.println("消息内容:"+msgString+"\t 消息摘要:"+sha1Hex2+"\t 验证签名:"+flag2);System.out.println("以上是JumpFly端接收消息解密.....");}

相关函数如下:

AESCoder :(在java加密与解密的艺术2相关代码中加以修改)

 private static final String KEY_ALGORITHM="AES";private static final String CIPHER_ALGORITHM="AES/ECB/PKCS5Padding";private static byte[] getKey(String key)throws Exception{return Base64.decodeBase64(key);}private static Key toKey(byte[] key)throws Exception{//实例化密钥材料SecretKey secretKey=new SecretKeySpec(key, KEY_ALGORITHM);return secretKey;}public static byte[] decrypt(byte[] data,byte[] key)throws Exception{//还原密钥Key K=toKey(key);Cipher cipher=Cipher.getInstance(CIPHER_ALGORITHM);cipher.init(Cipher.DECRYPT_MODE, K);return cipher.doFinal(data);}public static byte[] decrypt(byte[] data,String key)throws Exception{return decrypt(data, getKey(key));}public static byte[] encrypt(byte[] data,byte[] key)throws Exception{//还原密钥Key K=toKey(key);Cipher cipher=Cipher.getInstance(CIPHER_ALGORITHM);cipher.init(Cipher.ENCRYPT_MODE, K);return cipher.doFinal(data);}public static byte[] encrypt(byte[] data,String key)throws Exception{return encrypt(data, getKey(key));}public static void encryptFile(String FilePath,String EnFilePath,byte[] key)throws Exception{FileInputStream fileIn= new FileInputStream(FilePath);FileOutputStream fileOut=new FileOutputStream(EnFilePath);Key K=toKey(key);Cipher cipher=Cipher.getInstance(CIPHER_ALGORITHM);cipher.init(Cipher.ENCRYPT_MODE, K);crypt(fileIn, fileOut, cipher);}public static void encryptFile(String FilePath,String EnFilePath,String key)throws Exception{encryptFile(FilePath, EnFilePath, getKey(key));}public static void decryptFile(String EnFilePath,String DeFilePath,byte[] key)throws Exception{FileInputStream fileIn= new FileInputStream(EnFilePath);FileOutputStream fileOut=new FileOutputStream(DeFilePath);Key K=toKey(key);Cipher cipher=Cipher.getInstance(CIPHER_ALGORITHM);cipher.init(Cipher.DECRYPT_MODE, K);crypt(fileIn, fileOut, cipher);}public static void decryptFile(String EnFilePath,String DeFilePath,String key)throws Exception{decryptFile(EnFilePath, DeFilePath, getKey(key));}public static byte[] initKey()throws Exception{KeyGenerator kg=KeyGenerator.getInstance(KEY_ALGORITHM);kg.init(256);//生成秘密密钥SecretKey secretKey=kg.generateKey();return secretKey.getEncoded();}public static String initKeyString()throws Exception{return Base64.encodeBase64String(initKey());}public static void crypt(FileInputStream in,FileOutputStream out,Cipher cipher)throws IOException,GeneralSecurityException{FileChannel fcIn=null;MappedByteBuffer mbbfIn=null;int blockSize=cipher.getBlockSize();int outputSize=cipher.getOutputSize(blockSize);byte[] inBytes=new byte[blockSize];byte[] outBytes=new byte[outputSize];int len=0,outLenth;fcIn=in.getChannel();mbbfIn=fcIn.map(FileChannel.MapMode.READ_ONLY, 0, fcIn.size());boolean more=true;while(more){len=mbbfIn.limit()-mbbfIn.position();if(len>blockSize){  mbbfIn.get(inBytes, 0, blockSize);outLenth=cipher.update(inBytes, 0, blockSize, outBytes);out.write(outBytes,0,outLenth);}else{more=false;}} if(len>0){mbbfIn.get(inBytes, 0, len);outBytes=cipher.doFinal(inBytes,0,len);}else outBytes=cipher.doFinal();out.write(outBytes);if(fcIn!=null)fcIn.close();}

CertificateCoder:

public static byte[] sign(byte[] sign, String keyStorePath, String alias,String password) throws Exception {// 获得证书X509Certificate x509Certificate = (X509Certificate) getCertificate(keyStorePath, alias, password);// 构建签名,由证书指定签名算法Signature signature = Signature.getInstance(x509Certificate.getSigAlgName());// 获取私钥PrivateKey privateKey = getPrivateKeyByKeyStore(keyStorePath, alias,password);// 初始化签名,由私钥构建signature.initSign(privateKey);signature.update(sign);return signature.sign();}
public static byte[] encryptByPublicKey(byte[] data, String certificatePath)throws Exception {// 取得公钥PublicKey publicKey = getPublicKeyByCertificate(certificatePath);// 对数据加密Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());cipher.init(Cipher.ENCRYPT_MODE, publicKey);return cipher.doFinal(data);}
public static byte[] decryptByPrivateKey(byte[] data, String keyStorePath,String alias, String password) throws Exception {// 取得私钥PrivateKey privateKey = getPrivateKeyByKeyStore(keyStorePath, alias,password);// 对数据加密Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());cipher.init(Cipher.DECRYPT_MODE, privateKey);return cipher.doFinal(data);}

输出结果:

文件摘要:5417f2fe5eafc7b531a91ed391dbec89
数字签名:
c9a7884f64848c2e04c31a501c7f3301b504c8f7f5066f20800295808e28d3e20373b74466406590665107095fcb1afa413ca2d32cdf1c37ce23d61f6ca12e4aa7c6640aec07e92e837d43f9b65db0ce5e7d14dc893ce4271aa21027bdb660db2884e64e64ced5c208b0e7a8625e669cc23e247d02160e48dc7de6d164f591f2c99abb132a1afeb652af59d313e3b377eda46f4b74057d0e6cf59815461e6b99e37b3adac6e2295f499e4942db0eb5d81bee49304a4541c895b3647dd998690b249361e4b6bf34ceff01b172157057e4f224e5f6065a2bc748cfcb0c7fbf37066402164907a64ee7ad6d404ce3e3bd1f42939fa209f1a9c931f4a4c2d3567685
文件加密耗时: 12153 ms
以上是JumpFly端加密文件发送.....sign、Key、EnFile、EnKey
文件解密耗时: 12075 ms
文件摘要:5417f2fe5eafc7b531a91ed391dbec89 验证签名:true
以上是JumpFly2端接收文件解密.....
消息内容:这是JumpFly2端发送的消息 消息摘要:d5193b828c60194ef91c8af5617df68f6aa0cde4
数字签名:
6a43c3851407777c8b09f7c62899afecc1cc3c85a3f4037e1ef071dcd26c3380cb8db4b7d989756cc3247e9c44cbc4f9b68f77fa5379293a2b24ff4a2f8bbe2812b84a6a6861e9aad19ad3b0ed9e553f5cd1654aa146387d7b4354bebe126de00bff6990e7acb89f9b15f189c8b345498e7b0f7964c96d0156e88f473c9f23d97905d848a812ed7c1f1099f6f86d75aee67566b6f3aa8c60d52cf6127f43bd211f063503436e0535c9d6315e313feadac15eec604502645448e1e582079fb9e97d0059fa382db141c01e3183e6a7f45cd2f025846c0a01e0c10202f1e13397b605783df3b69a4f440c1ad9513c75dfcf72bc3543a76b8779edbb0394cab06ee1
以上是JumpFly2端加密消息发送.....sign2、EnMsg、EnKey2
消息内容:这是JumpFly2端发送的消息       消息摘要:d5193b828c60194ef91c8af5617df68f6aa0cde4  

验证签名:true
以上是JumpFly端接收消息解密.....

java证书加解密过程相关推荐

  1. python openssl 证书加解密过程感觉是这样

    python openssl 证书加解密过程感觉是这样 第一步 生成2048 bit的PEM格式的RSA Key:Key.pem openssl genrsa -out Key.pem -f4 204 ...

  2. java pkcs#11读取证书加解密(初学-分享)

    java pkcs#11读取证书加解密(初学-分享) http://www.cnblogs.com/sunfb/archive/2013/02/28/2937227.html 插入USB-KEY, 想 ...

  3. RSA算法原理——(3)RSA加解密过程及公式论证

    上期(RSA简介及基础数论知识)为大家介绍了:互质.欧拉函数.欧拉定理.模反元素 这四个数论的知识点,而这四个知识点是理解RSA加密算法的基石,忘了的同学可以快速的回顾一遍. 一.目前常见加密算法简介 ...

  4. RSA的加解密过程--(转自CSDN,学习用)

    RSA的加解密过程  public void StartDemo()  {   //RSA的加解密过程:   //  有 rsa1 和 rsa2 两个RSA对象.   //  现在要 rsa2 发送一 ...

  5. RSA加解密过程详解

    RSA加解密过程详解 RSA加密是一种非对称加密,由一对密钥来完成加解密过程,分别为公钥和私钥. RSA的加密过程如下: (1)A生成一对密钥(公钥和私钥),私钥不公开,A自己保留.公钥为公开的,任何 ...

  6. python加解密过程

    Python3开始,字符串和bytes类型彻底分开了,从此,字符串主要是给人看的,bytes类型是给计算机看的.Python3中最重要的新特性大概是对文本和二进制数据作了更为清晰的区分.文本默认总是U ...

  7. rsa java ao_RSA加解密工具类

    Java 实现 import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairG ...

  8. Java 3desede加解密_JAVA加解密11-对称加密算法-DES以及DESede算法

    一.简述 对称加密算法就是能将数据加解密.加密的时候用密钥对数据进行加密,解密的时候使用同样的密钥对数据进行解密. DES是美国国家标准研究所提出的算法.因为加解密的数据安全性和密钥长度成正比.des ...

  9. openresty 与 java RSA加解密

    上一篇搞定了openresty与java之间的aes加解密.这一篇就来说说openresty与java之间RSA的加解密.在测试的过程中.发现了与aes同样的问题.就是openresty支持的填充模式 ...

最新文章

  1. 科大讯飞“AI同传”造假背后的两个关键问题
  2. 自然语言处理(nlp)之词袋模型及句子相似度
  3. Python 在腾讯研发排第 5,鹅厂 2019 年新增 12.9 亿行代码
  4. 稀有名词解释——Java 堆污染(犄角旮旯问题)
  5. 对javascript闭包的理解
  6. 安卓:安卓工程构建及第一个安卓程序运行
  7. python3 开发面试题(collections中的Counter)6.7
  8. 崛起吧,亲爱的,该背单词了!!!
  9. colab加载google drive并且调试时跳过不运行
  10. qt 雷达扫描障碍物_自动驾驶系统入门(五) - 激光雷达
  11. 通用运输APP/小型物流托运APP/客运班车APP/PHP+MYSQL管理后端
  12. 力扣206-反转链表(Java,迭代)
  13. bzoj 1901: Zju2112 Dynamic Rankings(离线树状数组+主席树)
  14. Oracle搜索所有表查找关键字,根据关键字查询oracle中所有表的记录
  15. 【LitJson】如何判断字符串中是否有某个key
  16. 第二人生的源码分析(12)天空显示的实现
  17. java8 forkjoinpool_Java 普通线程池与 ForkJoinPool 的效果对比
  18. 多元函数泰勒级数展开_二元函数的泰勒展开二元函数的泰勒展开.pdf
  19. win10查看计算机管理员,win10系统下怎么获取administrator管理员权限
  20. 关于spyder环境配置

热门文章

  1. 基于阿里云物联网的体重秤
  2. 粗人之玩转Channel
  3. 养成记账好习惯,分享我的记账经验
  4. python 中的形参与实参
  5. 骷髅机器人素描图片大全_人物肖像素描的自我修炼2
  6. 想学BIM,一定要买高配置的电脑吗?
  7. 【ICPC46届上海站 Edge Groups】树形dp
  8. Linux服务器如何做raid1,Linux下制作raid1
  9. 飞翔的小鸟1.0 JAVA
  10. 一座宝塔_书是一座知识宝塔作文600字