原文:http://gaofulai1988.iteye.com/blog/2262802

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec; import javax.crypto.Cipher; import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder; /**
* RSA加密,支持分片加密
* <pre>
* BCD码(Binary-Coded Decimal‎)亦称二进码十进数或二-十进制代码。
* 用4位二进制数来表示1位十进制数中的0~9这10个数码。
* 是一种二进制的数字编码形式,用二进制编码的十进制代码。
* 注:日常所说的BCD码大都是指8421BCD码形式
* @author Ming
*
*/
public class RSAUtil {
/** 指定加密算法为RSA */
private static String ALGORITHM = "RSA";
/** 指定key的大小 */
private static int KEYSIZE = 1024;
/** 指定公钥存放文件 */
private static String PUBLIC_KEY_FILE = "d:/PublicKey";
/** 指定私钥存放文件 */
private static String PRIVATE_KEY_FILE = "d:/PrivateKey"; public static final String KEY_ALGORITHM = "RSA";
/** 自定义一个串 */
public static final String SIGNATURE_ALGORITHM = "shihaiming@#!RSA"; /**
* 生成密钥对
*/
public static void generateKeyPair() throws Exception {
if (getpublickey() == null || getprivatekey() == null) {
/** RSA算法要求有一个可信任的随机数源 */
SecureRandom sr = new SecureRandom();
/** 为RSA算法创建一个KeyPairGenerator对象 */
KeyPairGenerator kpg = KeyPairGenerator.getInstance(ALGORITHM);
/** 利用上面的随机数据源初始化这个KeyPairGenerator对象 */
kpg.initialize(KEYSIZE, sr);
/** 生成密匙对 */
KeyPair kp = kpg.generateKeyPair();
/** 得到公钥 */
Key publicKey = kp.getPublic();
/** 得到私钥 */
Key privateKey = kp.getPrivate();
/** 用对象流将生成的密钥写入文件 */
ObjectOutputStream oos1 = new ObjectOutputStream(new FileOutputStream(PUBLIC_KEY_FILE));
ObjectOutputStream oos2 = new ObjectOutputStream(new FileOutputStream(PRIVATE_KEY_FILE));
oos1.writeObject(publicKey);
oos2.writeObject(privateKey);
/** 清空缓存,关闭文件输出流 */
oos1.close();
oos2.close();
} } /**
* 产生签名
*
* @param data
* @param privateKey
* @return
* @throws Exception
*/
public static String sign(byte[] data, String privateKey) throws Exception {
// 解密由base64编码的私钥
byte[] keyBytes = decryptBASE64(privateKey); // 构造PKCS8EncodedKeySpec对象
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); // KEY_ALGORITHM 指定的加密算法
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 取私钥对象
PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec); // 用私钥对信息生成数字签名
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign(priKey);
signature.update(data); return encryptBASE64(signature.sign());
} /**
* 验证签名
*
* @param data
* @param publicKey
* @param sign
* @return
* @throws Exception
*/
public static boolean verify(byte[] data, String publicKey, String sign) throws Exception { // 解密由base64编码的公钥
byte[] keyBytes = decryptBASE64(publicKey); // 构造X509EncodedKeySpec对象
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); // KEY_ALGORITHM 指定的加密算法
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 取公钥对象
PublicKey pubKey = keyFactory.generatePublic(keySpec); Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(pubKey);
signature.update(data); // 验证签名是否有效
return signature.verify(decryptBASE64(sign));
} /**
* BASE64解密
*
* @param key
* @return
* @throws Exception
*/
public static byte[] decryptBASE64(String key) throws Exception {
return (new BASE64Decoder()).decodeBuffer(key);
} /**
* BASE64加密
*
* @param key
* @return
* @throws Exception
*/
public static String encryptBASE64(byte[] key) throws Exception {
return (new BASE64Encoder()).encodeBuffer(key);
} /**
* 加密方法 source: 源数据
*/
public static String encrypt(String source) throws Exception {
/** 将文件中的公钥对象读出 */
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(PUBLIC_KEY_FILE));
Key key = (Key) ois.readObject();
ois.close();
/** 得到Cipher对象来实现对源数据的RSA加密 */
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, key);
int MaxBlockSize = KEYSIZE / 8;
int len = (MaxBlockSize - 11) / 8;
String[] datas = splitString(source, len);
StringBuffer mi = new StringBuffer();
for (String s : datas) {
mi.append(bcd2Str(cipher.doFinal(s.getBytes())));
}
return mi.toString(); } /**
* 字符串分片
*
* @param string
* 源字符串
* @param len
* 单片的长度(keysize/8)
* @return
*/
public static String[] splitString(String string, int len) {
int x = string.length() / len;
int y = string.length() % len;
int z = 0;
if (y != 0) {
z = 1;
}
String[] strings = new String[x + z];
String str = "";
for (int i = 0; i < x + z; i++) {
if (i == x + z - 1 && y != 0) {
str = string.substring(i * len, i * len + y);
} else {
str = string.substring(i * len, i * len + len);
}
strings[i] = str;
}
return strings;
} /**
* bcd 转 Str
*
* @param bytes
* @return
*/
public static String bcd2Str(byte[] bytes) {
char temp[] = new char[bytes.length * 2], val;
for (int i = 0; i < bytes.length; i++) {
val = (char) (((bytes[i] & 0xf0) >> 4) & 0x0f);
temp[i * 2] = (char) (val > 9 ? val + 'A' - 10 : val + '0'); val = (char) (bytes[i] & 0x0f);
temp[i * 2 + 1] = (char) (val > 9 ? val + 'A' - 10 : val + '0');
}
return new String(temp);
} /**
* 解密
*
* @param cryptograph
* :密文
* @return 解密后的明文
* @throws Exception
*/
public static String decrypt(String cryptograph) throws Exception {
/** 将文件中的私钥对象读出 */
@SuppressWarnings("resource")
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(PRIVATE_KEY_FILE));
Key key = (Key) ois.readObject();
/** 得到Cipher对象对已用公钥加密的数据进行RSA解密 */
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, key);
int key_len = KEYSIZE / 8;
byte[] bytes = cryptograph.getBytes();
byte[] bcd = ASCII2BCD(bytes, bytes.length);
StringBuffer sBuffer = new StringBuffer();
byte[][] arrays = splitArray(bcd, key_len);
for (byte[] arr : arrays) {
sBuffer.append(new String(cipher.doFinal(arr)));
}
return sBuffer.toString();
} /**
* ASCII 转 BCD
*
* @param ascii
* @param asc_len
* @return
*/
public static byte[] ASCII2BCD(byte[] ascii, int asc_len) {
byte[] bcd = new byte[asc_len / 2];
int j = 0;
for (int i = 0; i < (asc_len + 1) / 2; i++) {
bcd[i] = asc2bcd(ascii[j++]);
bcd[i] = (byte) (((j >= asc_len) ? 0x00 : asc2bcd(ascii[j++])) + (bcd[i] << 4));
}
return bcd;
} /**
* asc转bcd
*
* @param asc
* @return
*/
public static byte asc2bcd(byte asc) {
byte bcd; if ((asc >= '0') && (asc <= '9'))
bcd = (byte) (asc - '0');
else if ((asc >= 'A') && (asc <= 'F'))
bcd = (byte) (asc - 'A' + 10);
else if ((asc >= 'a') && (asc <= 'f'))
bcd = (byte) (asc - 'a' + 10);
else
bcd = (byte) (asc - 48);
return bcd;
} /**
* 字节数组分片
*
* @param data
* @param len
* @return
*/
public static byte[][] splitArray(byte[] data, int len) {
int x = data.length / len;
int y = data.length % len;
int z = 0;
if (y != 0) {
z = 1;
}
byte[][] arrays = new byte[x + z][];
byte[] arr;
for (int i = 0; i < x + z; i++) {
arr = new byte[len];
if (i == x + z - 1 && y != 0) {
System.arraycopy(data, i * len, arr, 0, y);
} else {
System.arraycopy(data, i * len, arr, 0, len);
}
arrays[i] = arr;
}
return arrays;
} /** 将文件中的公钥对象读出 */
public static String getpublickey() { try {
@SuppressWarnings("resource")
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(PUBLIC_KEY_FILE));
Key key = (Key) ois.readObject();
String publickey = encryptBASE64(key.getEncoded());
return publickey;
} catch (Exception e) {
e.printStackTrace();
}
return null;
} /** 将文件中的私钥对象读出 */
public static String getprivatekey() {
try {
@SuppressWarnings("resource")
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(PRIVATE_KEY_FILE));
Key key = (Key) ois.readObject();
String privatekey = encryptBASE64(key.getEncoded());
return privatekey;
} catch (Exception e) {
e.printStackTrace();
}
return null;
} public static void main(String[] args) {
try {
//生成公钥、私钥文件
// generateKeyPair(); String s = encrypt("https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&ch=3");
System.out.println("加密:"+s);
System.out.println("解密:"+decrypt(s)); //再用base64加解密
String a = encryptBASE64(s.getBytes());
System.out.println(a);
String b = new String(decryptBASE64(a));
System.out.println(b);
System.out.println("解密b:"+decrypt(b));
} catch (Exception e) {
e.printStackTrace();
}
}
}

Java RSA 加密 解密 签名 验签的更多相关文章

  1. RSACryptoServiceProvider加密解密签名验签和DESCryptoServiceProvider加解密

    原文:RSACryptoServiceProvider加密解密签名验签和DESCryptoServiceProvider加解密 C#在using System.Security.Cryptograph ...

  2. js rsa sign使用笔记(加密,解密,签名,验签)

    你将会收获: js如何加密, 解密 js如何签名, 验签 js和Java交互如何相互解密, 验签(重点) 通过谷歌, 发现jsrsasign库使用者较多. 查看api发现这个库功能很健全. 本文使用方 ...

  3. C# RSACryptoServiceProvider加密解密签名验签和DESCryptoServic

    C#在using System.Security.Cryptography下有 DESCryptoServiceProvider RSACryptoServiceProvider DESCryptoS ...

  4. 支付接口中常用的加密解密以及验签rsa,md5,sha

    一.常用加密类型分类 1.对称加密:采用单钥对信息进行加密和解密,即同一个秘钥既可以对信息进行加密,也可以进行解密.此类型称之为对称加密.特点速度快,常用于对大量数据信息或文件加密时使用.常用例子:D ...

  5. RSA加密解密与加签验签

    RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest).阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的.1987年7月首次在美国公布 ...

  6. 【转】 java RSA加密解密实现

    [转] java RSA加密解密实现 该工具类中用到了BASE64,需要借助第三方类库:javabase64-1.3.1.jar 下载地址:http://download.csdn.net/detai ...

  7. iOS使用Security.framework进行RSA 加密解密签名和验证签名

    iOS 上 Security.framework为我们提供了安全方面相关的api: Security框架提供的RSA在iOS上使用的一些小结 支持的RSA keySize 大小有:512,768,10 ...

  8. Java使用RSA加密解密签名及校验

    RSA加密解密类: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 ...

  9. 数据安全管理:RSA加密算法,签名验签流程详解

    本文源码:GitHub·点这里 || GitEE·点这里 一.RSA算法简介 1.加密解密 RSA加密是一种非对称加密,在公开密钥加密和电子商业中RSA被广泛使用.可以在不直接传递密钥的情况下,完成加 ...

随机推荐

  1. poj 3050 地图5位数问题 dfs算法

    题意:一个5*5地图上面,从任意位置上下左右跳五次,组成一个数.问:不重复的数有多少个? 思路:dfs 从任意位置跳5次,说明每个位置都需要遍历. 组成一个数:number*10+map[dx][dy ...

  2. python基础学习笔记——类的成员

    一. 细分类的组成成员 之前咱们讲过类大致分两块区域,如下图所示: 每个区域详细划分又可以分为: class A: company_name = '老男孩教育' # 静态变量(静态字段) __ipho ...

  3. android adb虚拟机对应的键盘命令

    HOME                               Home button 主界面键 F2, PAGEUP                      Menu (Soft-Left) ...

  4. fiddler 抓包数据不会自动下拉解决方法

    选中 view 里面的 AutoScroll Session List 即可

  5. luogu1441 砝码称重

    搜索+背包就是了 #include <iostream> #include <cstring> #include <cstdio> using namespace ...

  6. 树链剖分 - Luogu 3384【模板】树链剖分

    [模板]树链剖分 题目描述 已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节点的值都加上z 操 ...

  7. Vue简单了解

    目录 1. 前端概览 2. 现代前端开发方式 3. MVVM开发核心 4. Vue核心 5. Vue优点 6. Vue难点 7. Vue与非Vue项目结合 8. Vue调试 9. Vue与SEO 今天 ...

  8. AutoEncoder and DenoiseAutoEncoder

    AutoEncoder and DenoiseAutoEncoder 第一部分 首先我们将实现一个如上图结构的最简单的AutoEncoder. 加载数据 在这里,我们使用MNIST手写数据集来进行实验 ...

  9. Linux定时任务Crontab命令详解 转

      linux 系统则是由 cron (crond) 这个系统服务来控制的.Linux 系统上面原本就有非常多的计划性工作,因此这个系统服务是默认启动的.另 外, 由于使用者自己也可以设置计划任务,所 ...

  10. 第001弹:Java 中创建对象的4种方式

    Java 是面向对象的语言,不可避免的,“对象”这个概念是 Java 语言的核心部分,这里来简单讨论一下在 Java 中创建一般对象的方法. 总结下来有以下4种创建对象的方法: 使用 new 关键字调 ...