修改後的RSA 加密解密 可用於製做liscence

       代碼修改於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; 
    } 
}
相關文章
相關標籤/搜索