RSA加密解密
来源:互联网 发布:加工中心proe软件 编辑:程序博客网 时间:2024/06/05 11:35
参考了网上的一些资料:
http://blog.sina.com.cn/s/blog_76550fd7010147tp.html
http://blog.csdn.net/centralperk/article/details/8538697
http://dustin.iteye.com/blog/763931
RSA算法密钥长度的选择是安全性和程序性能平衡的结果,密钥长度越长,安全性越好,加密解密所需时间越长。
1. 非对称加密算法中1024 bit密钥的强度相当于对称加密算法80bit密钥的强度。有资料上说以当前的软硬件水平,破解1024bit的RSA加密密文,需要一套10亿美金的系统使用若干十年的时间,所以2015年前,1024bit的还无需太担心暴力破解的危险。
2. 密钥长度增长一倍,公钥操作所需时间增加约4倍,私钥操作所需时间增加约8倍,公私钥生成时间约增长16倍。
3. 一次能加密的密文长度与密钥长度成正比, len_in_byte(raw_data) = len_in_bit(key)/8 -11,如1024bit的密钥,一次能加密的内容长度为 1024/8 -11 = 117 byte。所以非对称加密一般都用于加密对称加密算法的密钥,而不是直接加密内容。
4. 加密后密文的长度为密钥的长度,如密钥长度为1024b(128Byte),最后生成的密文固定为 1024b(128Byte)
现整理如下:
import java.io.*;import java.security.Key;import java.security.KeyFactory;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.interfaces.RSAPrivateKey;import java.security.interfaces.RSAPublicKey;import java.security.spec.PKCS8EncodedKeySpec;import java.security.spec.X509EncodedKeySpec;import javax.crypto.Cipher;public class RSAUtil{ private static final String KEY_ALGORITHM = "RSA";//签名算法 /** * RSA解密要求密文最大长度为128字节,加密明文最大长度117字节 * 如果加密数据过大需要在加密和解密的过程中需要分块进行 * 块数=(明文长度(bytes)/(密钥长度(需要将bit转换为bytes)-11))向上取整,就是不满一片的按一片算 * 所以密文的长度设置直接影响块数的大小,可以根据项目需要灵活分配分块的个数 * RSA最大密文长度 单位:byte */ private static final int DECRYPT_LENGTH = 128; /** * RSA最大明文长度 单位:byte */ private static final int ENCRYPT_LENGTH = DECRYPT_LENGTH - 11; /** *密钥长度 单位:bit 1byte=8bit *加密n byte的明文,需要至少(n+11)bytes的密钥 *因为该单位是bit 所以换算成bit就要乘以8 */ private static final int ENCRYTLENGTH = (ENCRYPT_LENGTH + 11) * 8; /** * 注意下面两个路径必须存在,否则在初始化过程中会发生异常 */ private static final String PUBLICKEYPATH = "/home/key/public.key"; private static final String PRIVATEKEYPATH = "/home/key/private.key"; private static RSAPublicKey publicKey; private static RSAPrivateKey privateKey; public enum KeyType{ PUBLIC,PRIVATE; } static{ try { initKey(true); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("初始化key异常!!"); } } public static void main(String[] args) throws Exception { String data = "hello world"; File publickeyFile = new File(PUBLICKEYPATH); File privatekeyFile = new File(PRIVATEKEYPATH); byte[] encryptData,decryptData; if(publickeyFile.exists() && privatekeyFile.exists()){ Key publickey = getKey(publickeyFile, KeyType.PUBLIC); Key privatekey = getKey(privatekeyFile, KeyType.PRIVATE); encryptData = encrypt(data.getBytes(), publickey); decryptData = decrypt(encryptData, privatekey); System.out.println("用文件路径方式的key进行加密!!!"); }else{ encryptData = encrypt(data.getBytes()); decryptData = decrypt(encryptData); System.out.println("用系统初始化的key进行加密!!!"); } System.out.println("加密后:" + new String(encryptData, "UTF-8")); System.out.println(new String(decryptData)); } /** * @param isSaveKey //初始化是否将key保存为文件 true是 false不是 * @throws Exception */ private static void initKey(boolean isSaveKey) throws Exception { KeyPairGenerator kg = KeyPairGenerator.getInstance(KEY_ALGORITHM); kg.initialize(ENCRYTLENGTH); KeyPair keypair = kg.generateKeyPair(); //得到公钥和私钥 publicKey = (RSAPublicKey) keypair.getPublic(); privateKey = (RSAPrivateKey) keypair.getPrivate(); if(isSaveKey){ File publicKeyFile = new File(PUBLICKEYPATH); File privateKeyFile = new File(PRIVATEKEYPATH); if(publicKeyFile.exists() && privateKeyFile.exists()){ generateKeyToFile(publicKey, publicKeyFile); generateKeyToFile(privateKey, privateKeyFile); }else{ throw new RuntimeException("生成key文件的路径错误!!!"); } } } /** * 将key生成到文件 * @param key * @param file * @return * @throws IOException */ private static boolean generateKeyToFile(Key key,File file) throws IOException { boolean flag = false; FileOutputStream fos = null; ObjectOutputStream oos = null; try { fos = new FileOutputStream(file); oos = new ObjectOutputStream(fos); //公钥默认使用的是X.509编码,私钥默认采用的是PKCS8编码 byte [] encode = key.getEncoded(); //注意,此处采用writeObject方法,读取时也要采用readObject方法 oos.writeObject(encode); flag = true; } catch (IOException e) { throw e; } finally { if(fos != null) fos.close(); if(oos != null) oos.close(); } return flag; } /** * @param keybyte * @param type * @return * @throws Exception */ private static Key getKey( byte[] keybyte, KeyType type) throws Exception { KeyFactory keyfactory = KeyFactory.getInstance(KEY_ALGORITHM); if (type == KeyType.PUBLIC) { X509EncodedKeySpec x509eks = new X509EncodedKeySpec(keybyte); RSAPublicKey publicKey = (RSAPublicKey) keyfactory.generatePublic(x509eks); return publicKey; } else if (type == KeyType.PRIVATE) { PKCS8EncodedKeySpec pkcs8eks = new PKCS8EncodedKeySpec(keybyte); RSAPrivateKey privateKey = (RSAPrivateKey) keyfactory.generatePrivate(pkcs8eks); return privateKey; } return null; } /** * @param keyFile * @param type * @return * @throws Exception */ private static Key getKey(File keyFile, KeyType type) throws Exception { FileInputStream fis = new FileInputStream(keyFile); ObjectInputStream ois = new ObjectInputStream(fis); byte[] keybyte = (byte[]) ois.readObject(); ois.close(); return getKey(keybyte,type); } /** * @param type * @return * @throws Exception */ private static Key getKey(KeyType type) throws Exception { if (type == KeyType.PUBLIC) { return publicKey; } else if (type == KeyType.PRIVATE) { return privateKey; } return null; } /** * @param data * @param publicKey * @return * @throws Exception */ private static byte[] encrypt(byte[] data, Key publicKey) throws Exception { Cipher cipher = Cipher.getInstance(KEY_ALGORITHM); 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 > ENCRYPT_LENGTH) { cache = cipher.doFinal(data, offSet, ENCRYPT_LENGTH); } else { cache = cipher.doFinal(data, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * ENCRYPT_LENGTH; } byte[] encryptedData = out.toByteArray(); out.close(); return encryptedData; } /** * @param data * @param keyFile * @return * @throws Exception */ public static byte[] encrypt(byte[] data,File keyFile) throws Exception { Key publicKey = getKey(keyFile, KeyType.PUBLIC); return encrypt(data,publicKey); } /** * @param data * @param keyByte * @return * @throws Exception */ public static byte[] encrypt(byte[] data,byte[] keyByte) throws Exception { Key publicKey = getKey(keyByte,KeyType.PUBLIC); return encrypt(data,publicKey); } /** * @param data * @return * @throws Exception */ public static byte[] encrypt(byte[] data) throws Exception { return encrypt(data,publicKey); } /** * * @param data * @param privateKey * @return * @throws Exception */ private static byte[] decrypt(byte[] data, Key privateKey) throws Exception { Cipher cipher = Cipher.getInstance(KEY_ALGORITHM); 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 > DECRYPT_LENGTH) { cache = cipher.doFinal(data, offSet, DECRYPT_LENGTH); } else { cache = cipher.doFinal(data, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * DECRYPT_LENGTH; } byte[] decryptedData = out.toByteArray(); out.close(); return decryptedData; } /** * @param data * @param privateKeyBytes * @return * @throws Exception */ public static byte[] decrypt(byte[] data, byte[] privateKeyBytes) throws Exception { Key privateKey = getKey(privateKeyBytes,KeyType.PRIVATE); return decrypt(data,privateKey); } /** * @param data * @param keyFile * @return * @throws Exception */ public static byte[] decrypt(byte[] data,File keyFile) throws Exception { Key privateKey = getKey(keyFile, KeyType.PRIVATE); return decrypt(data,privateKey); } /** * @param data * @return * @throws Exception */ public static byte[] decrypt(byte[] data) throws Exception { return decrypt(data,privateKey); }}
0 0
- RSA加密、解密
- RSA加密解密
- 加密解密---------->RSA算法
- RSA 加密解密总结
- RSA加密解密-实例
- RSA简单加密解密
- RSA加密解密算法
- RSA加密解密算法
- java RSA加密解密
- Java RSA加密解密
- RSA加密解密操作
- RSA加密与解密
- Java RSA加密解密
- RSA加密解密
- java RSA 加密/解密
- RSA加密解密
- RSA加密和解密
- java RSA加密解密
- 【Android开发基础】应用界面主题Theme使用方法
- jQuery中关于bind() live()方法的区别
- dedecms模板设计 > 模板标签语法简介
- 这只是一个梦
- DDR3中bank, 16bit和32bit等概念
- RSA加密解密
- 【DB.PL/SQL】程序流程控制 —— 循环 ——LOOP, END LOOP, WHILE, FOR, CONTINUE
- 《Systems Performance: Enterprise and the Cloud》读书笔记系列(七) —— 第二章(六)
- jquery---如何获取select下拉框当前选择的文本
- OnGestureListener和listView以及GridView冲突的解决办法
- 【黑马程序员】网络编程(十)
- DedeCMS子栏目在子栏目或内容页,调用所在顶级栏目的栏目名
- vs2010 MsgPack的编译报错:MSGPACK_STD_TR1 无定义
- TCP/IP协议与Socket通信