前言:近期公司做数据加密及签名,整理如下:

一、数字签名。

是只有信息的发送者才能产生的别人无法伪造的一段数字串,具有不可抵赖性,可验证信息完整性的一种手段。

签名不可伪造:其他人因为没有对应的私钥,所以没法生成公钥可以解密的密文,所以是不可伪造的。

过程为:

1.A对消息M计算摘要,得到摘要H(可以采用MD5,因为MD5具有唯一性且不可逆)。

2.A利用自己的私钥对H进行签名得到Sign(即加密,可以采用RSA)

二、消息加密

可采用DESede算法进行加密,需要获取密钥对。

三、消息加密,并进行签名

1.A生成消息M。

2.利用MD5加密M生成摘要H(就是生成16字节的散列值)。

3.利用A的私钥(因为私钥保护的好是不可能外露的,加密后的消息是不可能被其他公钥解密的)对H进行加密,生成签名Sign。

4.将M通过DESede进行加密,生成加密消息R。

5.将Sign和R进行Base64编码后发送给B。

四、解密

1.解密消息R,生成原文P。

2.利用A的公钥解密签名Sign生成B。

3.对P进行MD5加密,并与B进行比较,如果一致说明没有被修改过。

五、代码(以下代码已验证)

import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import kh.pms.tools.StringUtil; /**
* 签名验签及加密 1.对原文进行des加密。 2.des加密数据进行md5。 3.用我方私钥进行md5的签名。 4.用我方公钥对des加密数据进行加密
*
* @author chx
*
*/
public class MD5withRSA {
private static final String FLAG_RSA = "RSA";
private static final String SIGNATURE_ALGORITHM = "MD5withRSA";
/**
* 我方私钥对象
*/
private PrivateKey myPrivateKeyObj; /**
* 银行方公钥对象
*/
private PublicKey bankPublicKeyObj; /**
* 获取签名
*
* @return
* @throws Exception
*/
public byte[] getSign(String str) throws Exception {
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);// 签名的算法
signature.initSign(myPrivateKeyObj);
signature.update(str.getBytes());
return signature.sign();
} /**
* 析构函数
*
* @param plain
* 待加解密原文
* @throws Exception
*/
public MD5withRSA() throws Exception {
myPrivateKeyObj = getPrivateKey();
      //将此处的JianHangUtil.bankPublicKey更换为自己的公钥字符串(base64格式),后面的
bankPublicKeyObj = getPublicKey(JianHangUtil.bankPublicKey);
} /**
* 通过预制公钥生成PublicKey
*
* @param pubKey
* @return
* @throws Exception
*/
private PublicKey getPublicKey(String key) throws Exception {
byte[] encoded = StringUtil.getBaseStrJie(key);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encoded);
KeyFactory factory = KeyFactory.getInstance(FLAG_RSA);
return factory.generatePublic(keySpec);
} /**
* 将指定的字符串转换为私钥key
*
* @param priKey
* @return
* @throws Exception
*/
private PrivateKey getPrivateKey() throws Exception {
// 首先进行base64解码。
byte[] encoded = StringUtil.getBaseStrJie(JianHangUtil.myPrivateKey);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
KeyFactory factory = KeyFactory.getInstance(FLAG_RSA);
return factory.generatePrivate(keySpec);
} /**
* 验证签名
*
* @param data
* 原文
* @param mySign
* 签名
* @return
* @throws Exception
*/
public boolean yanZhengSign(byte[] data, byte[] mySign) throws Exception {
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(bankPublicKeyObj);
signature.update(data);
return signature.verify(mySign);
}

加解密:

package kh.pms.bank;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import kh.pms.tools.StringUtil; /**
* 报文加解密工具(注意,本类所有方法均会进行base64解码)
*
* @author chx
*
*/
public class DESedeCoder {
/**
* 密钥算法
*/
private static String KEY_ALGORITHM = "DESede";
private static String DEFAULT_CIPHER_ALGORITHM = "DESede/ECB/PKCS5Padding"; /**
* 加密(会对des和公钥进行base64解码)
*
* @param data
* 待加密数据
* @param key
* 密钥
* @return byte[] 加密数据
* @throws Exception
*/
public byte[] encrypt(byte[] src) throws Exception {
DESedeKeySpec dks = new DESedeKeySpec(StringUtil.getBaseStrJie(JianHangUtil.desKey));
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(KEY_ALGORITHM);
SecretKey securekey = keyFactory.generateSecret(dks);
Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, securekey);
return cipher.doFinal(src);
} /**
* 解密
*
* @param data
* 待解密数据
* @param key
* 密钥
* @return byte[] 解密数据
* @throws Exception
*/
public byte[] decrypt(byte[] data) throws Exception {
// 加解密的deskey(需更换为自己的des密钥)
DESedeKeySpec dks = new DESedeKeySpec(StringUtil.getBaseStrJie(JianHangUtil.desKey));
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(KEY_ALGORITHM);
SecretKey securekey = keyFactory.generateSecret(dks);
Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, securekey);
return cipher.doFinal(data);
}
}

最新文章

  1. ROS学习(三)—— ROS文件系统
  2. 《利用Python进行数据分析》第123章学习笔记
  3. 教你一招 - 如何给nopcommerce增加一个类似admin的area
  4. 用户授权 OAuth 2.0
  5. WindowsService 安装后报错: 无法启动计算机“.”上的服务 解决方案
  6. 常用的几种 SQLServer 分页查询方式实现
  7. uimodalpresentationformsheet resize ios7
  8. SpringMVC + Spring + MyBatis 学习笔记:SpringMVC和Spring一同工作的时候,AOP事务管理不起作用的解决方法
  9. phpcms加载系统类与加载应用类之区别详解
  10. ORA-00937:不是单组分组函数_Oracle
  11. 在JBuilder8中使用ANT
  12. r.js实践
  13. 随机函数Surprising
  14. RandomShuffleQueue
  15. Android的Activity组件
  16. python 读取csv 数据并画图分析
  17. Python _Mix*9
  18. Python的学习计划
  19. 《OpenCL异构并行编程实战》补充笔记散点,第一至四章
  20. ERRORS:<class 'Salesman.admin.UsrMngUserAdmin'>: (admin.E005) Both 'fieldsets' and 'fields' are specified.

热门文章

  1. SpringMVC学习(4):数据绑定1 @RequestParam
  2. LLppdd has a dream!
  3. elastic插件安装
  4. cd 切换
  5. koa 的 Context
  6. php 学习一 变量的定义
  7. 71 Serializable(序列化和反序列化)
  8. phpass类加密算法
  9. java 获取String出现最多次数的字段
  10. Unity HOME