代碼修改於http://my.oschina.net/sky8wolf/blog/131217?p=1#rpl_273754932,發現有不少錯誤和不合理的地方,好比異常的處理,生成licence,保存祕鑰文件(注意,保存祕鑰是爲了解密licence,他博客的那個PrivateKey那裏其實就是想保存祕鑰中用於解密的兩端內容,也就是d和n)等。也爲關鍵代碼作了介紹。軟件的運行須要導入json-lib包,json-lib的運行須要依賴commons-beanutils、commons-collections、commons-lang、commons-logging、ezmorph包,能夠從官網下載便可。java
package rsa; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.interfaces.RSAPrivateCrtKey; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import net.sf.json.JSONObject; import sun.security.rsa.RSAPrivateCrtKeyImpl; public class RSA { public static void main(String[] args) { String[] strs = gen_RSA(1024); String e = strs[0]; //System.out.println("e\n"+e); String n = strs[1]; //System.out.println("n\n"+n); String d = strs[2]; //System.out.println("d\n"+d); //不過時時間 long deadline=System.currentTimeMillis()+1000000; //過時時間 //long deadline=System.currentTimeMillis(); String mingwen="{name:'軟件名稱',deadline:'"+deadline+"'}"; //System.out.println("加密前明文\n"+mingwen); String miwen = Enc_RSA(mingwen, e, n); //System.out.println("加密後密文\n"+miwen); String str2 = Dec_RSA(miwen, d, n); System.out.println("解密後明文\n"+str2); ObjectOutputStream oos = null; try { //保存licence oos = new ObjectOutputStream(new FileOutputStream(new File("./tmp/mobile.lic"))); oos.writeObject(miwen); oos.flush(); oos.close(); } catch (IOException e1) { e1.printStackTrace(); } checkLicence(); } /** * 檢查licence是否到期 */ public static void checkLicence() { //licFile存放密文 String licFile = "./tmp/mobile.lic"; //祕鑰,用於解密密文 String privateKeyFile = "./tmp/private.key"; //獲得解密的內容 String licence = decrypt(licFile, privateKeyFile); if (licence != null) { JSONObject json = JSONObject.fromObject(licence); String name = json.getString("name"); //轉換成時間 long deadline = Long.parseLong(json.getString("deadline")); System.out.println(name+deadline); String companyName = ""; if ((!companyName.equals(name)) && (deadline < System.currentTimeMillis())) { System.out.println("系統未受權或已過時,請聯繫做者進行註冊,謝謝!"); }else{ System.out.println("系統受權,謝謝!"); } } else { System.out.println("系統未受權或已過時,請聯繫做者進行註冊,謝謝!"); } } /** * 解密文件 獲得json格式的內容 * @param licFile 密文 * @param privateKeyFile 祕鑰 * @return 返回內容格式以下 { name:'',deadline:'1371362586906'} */ public static String decrypt(String licFile, String privateKeyFile) { try { ObjectInputStream b1 = new ObjectInputStream(new FileInputStream(licFile)); String miwen=(String) b1.readObject(); BigInteger c = new BigInteger(miwen); FileInputStream f = new FileInputStream(privateKeyFile); ObjectInputStream b = new ObjectInputStream(f); RSAPrivateKey privateKey = (RSAPrivateKey) b.readObject(); BigInteger d = privateKey.getPrivateExponent(); BigInteger n = privateKey.getModulus(); //解密 BigInteger m = c.modPow(d, n); byte[] mt = m.toByteArray(); return new String(mt, "utf-8"); } catch (Exception e) { e.printStackTrace(); } return null; } /** * 生成並祕鑰對 * @param keylen 輸入密鑰長度 * @return 返回公鑰和私鑰 */ public static Object[] get_RSA(int keylen) { Object[] output = new Object[2]; try { KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); kpg.initialize(keylen); // 指定密鑰的長度,初始化密鑰對生成器 KeyPair kp = kpg.generateKeyPair(); // 生成密鑰對 //公鑰 RSAPublicKey puk = (RSAPublicKey) kp.getPublic(); //私鑰 RSAPrivateCrtKey prk = (RSAPrivateCrtKeyImpl) kp.getPrivate(); output[0] = puk; output[1] = prk; } catch (Exception ex) { } return output; } /** * 生成祕鑰對,返回能用於加解密的字符串數組,祕鑰對不會被保存 * @param keylen 輸入密鑰長度 * @return 用於加解密的字符串數組 */ public static String[] gen_RSA(int keylen) { String[] output = new String[5]; // 用來存儲密鑰的 e n d p q try { KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); kpg.initialize(keylen); // 指定密鑰的長度,初始化密鑰對生成器 KeyPair kp = kpg.generateKeyPair(); // 生成密鑰對 //公鑰 RSAPublicKey puk = (RSAPublicKey) kp.getPublic(); //私鑰 RSAPrivateCrtKey prk = (RSAPrivateCrtKeyImpl) kp.getPrivate(); ObjectOutputStream oos = null; try { //保存私鑰 oos = new ObjectOutputStream(new FileOutputStream(new File("./tmp/private.key"))); oos.writeObject(prk); oos.flush(); oos.close(); } catch (IOException e1) { e1.printStackTrace(); } BigInteger e = puk.getPublicExponent(); BigInteger n = puk.getModulus(); BigInteger d = prk.getPrivateExponent(); BigInteger p = prk.getPrimeP(); BigInteger q = prk.getPrimeQ(); output[0] = e.toString(); output[1] = n.toString(); output[2] = d.toString(); output[3] = p.toString(); output[4] = q.toString(); } catch (Exception ex) { } return output; } /** * 加密,在RSA公鑰中包含有兩個整數信息:e和n。對於明文數字m,計算密文的公式是m的e次方再與n求模。 * @param mingwen 明文 * @param eStr e * @param nStr n * @return 返回密文 */ public static String Enc_RSA(String mingwen, String eStr, String nStr) { String miwen = new String(); try { BigInteger e = new BigInteger(eStr); BigInteger n = new BigInteger(nStr); byte[] ptext = mingwen.getBytes("utf-8"); BigInteger m = new BigInteger(ptext); BigInteger c = m.modPow(e, n); miwen = c.toString(); } catch (Exception ex) { } return miwen; } /** * 解密 * @param miwen * @param dStr d * @param nStr n * @return */ public static String Dec_RSA(String miwen, String dStr, String nStr) { String mingwen = null; try { BigInteger d = new BigInteger(dStr);// 獲取私鑰的參數d,n BigInteger n = new BigInteger(nStr); BigInteger c = new BigInteger(miwen); BigInteger m = c.modPow(d, n);// 解密明文 byte[] mt = m.toByteArray();// 計算明文對應的字符串並輸出 mingwen= new String(mt, "utf-8"); } catch (Exception e) { e.printStackTrace(); } return mingwen; } }