package jef.tools.security; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import java.security.SecureRandom; import java.util.HashMap; import java.util.Hashtable; import java.util.Map; public class RSA { private final static SecureRandom random = new SecureRandom(); private BigInteger a; private BigInteger b; private BigInteger n; private BigInteger p; private BigInteger q; private Map<String, BigInteger> publicKey; private Map<String, BigInteger> privateKey; /** * 获取密钥 * @return 密钥 */ public Map<String, BigInteger> getPrivateKey() { return privateKey; } /** * 设置密钥 * @param privateKey 密钥 */ public void setPrivateKey(Map<String, BigInteger> privateKey) { this.privateKey = privateKey; p = privateKey.get("p"); q = privateKey.get("q"); a = privateKey.get("a"); n = p.multiply(q); } /** * 获取公钥 * @return 公钥 */ public Map<String, BigInteger> getPublicKey() { return publicKey; } /** * 设置公钥 * @param publicKey 公钥 */ public void setPublicKey(Hashtable<String, BigInteger> publicKey) { this.publicKey = publicKey; n = publicKey.get("n"); b = publicKey.get("b"); } /** * 产生长度为N位的公钥和私钥 * @param N */ public void genKey(int N) { // 产生两个N/2位的大素数p和q p = BigInteger.probablePrime(N/2, random); q = BigInteger.probablePrime(N/2, random); // 计算(p-1)*(q-1) BigInteger phi = (p.subtract(BigInteger.ONE)).multiply(q.subtract(BigInteger.ONE)); // 计算模数p*q n = p.multiply(q); // 随便找一个b,使得gcd(b, phi) =1; // 通用的公钥是2^16 + 1=65537 b = new BigInteger("65537"); // 计算出a,即b的模n逆 a = b.modInverse(phi); publicKey = new HashMap<String, BigInteger>(); privateKey = new HashMap<String, BigInteger>(); publicKey.put("n", n); publicKey.put("b", b); privateKey.put("p", p); privateKey.put("q", q); privateKey.put("a", a); } /** * 加密函数 * @param plainText 明文 * @return 密文 */ public byte[] encrypt(byte[] plainText) { return new BigInteger(plainText).modPow(b, n).toByteArray(); } /** * 解密函数 * @param cipherText 密文 * @return 明文 */ public byte[] decrypt(byte[] cipherText) { return new BigInteger(cipherText).modPow(a, n).toByteArray(); } public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException { RSA rsa = new RSA(); rsa.genKey(1024); // 产生密钥 // 保存私钥到文件 key ObjectOutputStream keyout = new ObjectOutputStream(new FileOutputStream("key")); keyout.writeObject(rsa.getPrivateKey()); keyout.flush(); keyout.close(); // 加密一句消息 byte[] cipher = rsa.encrypt("s你是最棒的".getBytes("gbk")); // 将加密消息写入文件 ObjectOutputStream fileout = new ObjectOutputStream(new FileOutputStream("file")); fileout.writeObject(cipher); fileout.flush(); // 读入密钥 ObjectInputStream keyin = new ObjectInputStream(new FileInputStream("key")); RSA rsa1 = new RSA(); Map<String, BigInteger> privateKey = (Map<String, BigInteger>)keyin.readObject(); rsa1.setPrivateKey(privateKey); keyin.close(); ObjectInputStream filein = new ObjectInputStream(new FileInputStream("file")); byte[] cp = (byte[])filein.readObject(); // 解密 byte[] plain = rsa1.decrypt(cp); System.out.println(new String(plain,"gbk")); } }