package sinRsa; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; 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 org.apache.commons.codec.binary.Base64; public class RSAUtil { // 数字签名,密钥算法 private static final String RSA_KEY_ALGORITHM = "RSA"; // 数字签名签名/验证算法 private static final String SIGNATURE_ALGORITHM = "MD5withRSA"; // RSA密钥长度 private static final int KEY_SIZE = 1024; //RSA最大加密明文大小 private static final int MAX_ENCRYPT_BLOCK = 117; //RSA最大解密密文大小 private static final int MAX_DECRYPT_BLOCK = 128; /** * 初始化RSA密钥对 * @return RSA密钥对 * @throws Exception 抛出异常 */ private static void initKey(String pubkeyfile, String privatekeyfile) throws Exception { KeyPairGenerator keygen = KeyPairGenerator .getInstance(RSA_KEY_ALGORITHM); SecureRandom secrand = new SecureRandom(); secrand.setSeed("hahaha".getBytes());// 初始化随机产生器 keygen.initialize(KEY_SIZE, secrand); // 初始化密钥生成器 KeyPair keys = keygen.genKeyPair(); String pub_key = Base64.encodeBase64String(keys.getPublic().getEncoded()); String pri_key = Base64.encodeBase64String(keys.getPrivate().getEncoded()); // 生成私钥 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream( privatekeyfile)); oos.writeObject(pri_key); oos.flush(); oos.close(); // 生成公钥 oos = new ObjectOutputStream(new FileOutputStream(pubkeyfile)); oos.writeObject(pub_key); oos.flush(); oos.close(); System.out.println("公钥:" + pub_key); System.out.println("私钥:" + pri_key); } /** * 数字签名 * @param data 待签名数据 * @param pri_key 私钥 * @return 签名 * @throws Exception 抛出异常 */ public static String sign(byte[] data, String pri_key) throws Exception { // 取得私钥 byte[] pri_key_bytes = Base64.decodeBase64(pri_key); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(pri_key_bytes); KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM); // 生成私钥 PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec); // 实例化Signature Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); // 初始化Signature signature.initSign(priKey); // 更新 signature.update(data); return Base64.encodeBase64String(signature.sign()); } /** * RSA校验数字签名 * @param data 数据 * @param sign 签名 * @param pub_key 公钥 * @return 校验结果,成功为true,失败为false * @throws Exception 抛出异常 */ public boolean verify(byte[] data, byte[] sign, String pub_key) throws Exception { // 转换公钥材料 // 实例化密钥工厂 byte[] pub_key_bytes = Base64.decodeBase64(pub_key); KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM); // 初始化公钥 // 密钥材料转换 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(pub_key_bytes); // 产生公钥 PublicKey pubKey = keyFactory.generatePublic(x509KeySpec); // 实例化Signature Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); // 初始化Signature signature.initVerify(pubKey); // 更新 signature.update(data); // 验证 return signature.verify(sign); } /** * 公钥加密 * @param data 待加密数据 * @param pub_key 公钥 * @return 密文 * @throws Exception 抛出异常 */ private static byte[] encryptByPubKey(byte[] data, byte[] pub_key) throws Exception { // 取得公钥 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(pub_key); KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM); PublicKey publicKey = keyFactory.generatePublic(x509KeySpec); // 对数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicKey); int inputLen = data.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK); } else { cache = cipher.doFinal(data, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_ENCRYPT_BLOCK; } byte[] encryptedData = out.toByteArray(); out.close(); return encryptedData; } /** * 公钥加密 * @param data 待加密数据 * @param pub_key 公钥 * @return 密文 * @throws Exception 抛出异常 */ public static String encryptByPubKey(String data, String pub_key) throws Exception { // 私匙加密 byte[] pub_key_bytes = Base64.decodeBase64(pub_key); byte[] enSign = encryptByPubKey(data.getBytes(), pub_key_bytes); return Base64.encodeBase64String(enSign); } /** * 私钥加密 * @param data 待加密数据 * @param pri_key 私钥 * @return 密文 * @throws Exception 抛出异常 */ private static byte[] encryptByPriKey(byte[] data, byte[] pri_key) throws Exception { // 取得私钥 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(pri_key); KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM); PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec); // 对数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, privateKey); int inputLen = data.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK); } else { cache = cipher.doFinal(data, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_ENCRYPT_BLOCK; } byte[] encryptedData = out.toByteArray(); out.close(); return encryptedData; } /** * 私钥加密 * @param data 待加密数据 * @param pri_key 私钥 * @return 密文 * @throws Exception 抛出异常 */ public static String encryptByPriKey(String data, String pri_key) throws Exception { // 私匙加密 byte[] pri_key_bytes = Base64.decodeBase64(pri_key); byte[] enSign = encryptByPriKey(data.getBytes(), pri_key_bytes); return Base64.encodeBase64String(enSign); } /** * 公钥解密 * @param data 待解密数据 * @param pub_key 公钥 * @return 明文 * @throws Exception 抛出异常 */ private static byte[] decryptByPubKey(byte[] data, byte[] pub_key) throws Exception { // 取得公钥 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(pub_key); KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM); PublicKey publicKey = keyFactory.generatePublic(x509KeySpec); // 对数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, publicKey); int inputLen = data.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_DECRYPT_BLOCK) { cache = cipher.doFinal(data, offSet, MAX_DECRYPT_BLOCK); } else { cache = cipher.doFinal(data, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_DECRYPT_BLOCK; } byte[] decryptedData = out.toByteArray(); out.close(); return decryptedData; } /** * 公钥解密 * @param data 待解密数据 * @param pub_key 公钥 * @return 明文 * @throws Exception 抛出异常 */ public static String decryptByPubKey(String data, String pub_key) throws Exception { // 公匙解密 byte[] pub_key_bytes = Base64.decodeBase64(pub_key); byte[] design = decryptByPubKey(Base64.decodeBase64(data), pub_key_bytes); return new String(design); } /** * 私钥解密 * @param data 待解密数据 * @param pri_key 私钥 * @return 明文 * @throws Exception 抛出异常 */ private static byte[] decryptByPriKey(byte[] data, byte[] pri_key) throws Exception { // 取得私钥 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(pri_key); KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM); PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec); // 对数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privateKey); int inputLen = data.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_DECRYPT_BLOCK) { cache = cipher.doFinal(data, offSet, MAX_DECRYPT_BLOCK); } else { cache = cipher.doFinal(data, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_DECRYPT_BLOCK; } byte[] decryptedData = out.toByteArray(); out.close(); return decryptedData; } /** * 私钥解密 * @param data 待解密数据 * @param pri_key 私钥 * @return 明文 * @throws Exception 抛出异常 */ public static String decryptByPriKey(String data, String pri_key) throws Exception { // 私匙解密 byte[] pri_key_bytes = Base64.decodeBase64(pri_key); byte[] design = decryptByPriKey(Base64.decodeBase64(data), pri_key_bytes); return new String(design); } /** * @param args */ public static void main(String[] args) throws Exception { String pubfile = "d:/temp/pub.key"; String prifile = "d:/temp/pri.key"; initKey(pubfile,prifile); //获取公钥 ObjectInputStream ois = new ObjectInputStream(new FileInputStream(pubfile)); String pub_key = (String) ois.readObject(); ois.close(); //获取私钥 ois = new ObjectInputStream(new FileInputStream(prifile)); String pri_key = (String) ois.readObject(); ois.close(); RSAUtil das = new RSAUtil(); String datastr = "这是我第一次写rsa加密。"; System.out.println("待加密数据:\n" + datastr); // 公匙加密 String pubKeyStr = RSAUtil.encryptByPubKey(datastr, pub_key); System.out.println("公匙加密结果:\n" + pubKeyStr); // 私匙解密 String priKeyStr = RSAUtil.decryptByPriKey(pubKeyStr, pri_key); System.out.println("私匙解密结果:\n" + priKeyStr); //换行 System.out.println(); // 数字签名 String str1 = "天地玄黄"; String str2 = "宇宙洪荒"; System.out.println("正确的签名:" + str1 + "\n错误的签名:" + str2); String sign = RSAUtil.sign(str1.getBytes(), pri_key); System.out.println("数字签名:\n" + sign); boolean vflag1 = das.verify(str1.getBytes(), Base64.decodeBase64(sign), pub_key); System.out.println("数字签名验证结果1:\n" + vflag1); boolean vflag2 = das.verify(str2.getBytes(), Base64.decodeBase64(sign), pub_key); System.out.println("数字签名验证结果2:\n" + vflag2); } }