現在很多J2EE應用都采用一個license文件來授權系統的使用,特別是在系統購買的早期,會提供有限制的license文件對系統進行限制,比如試用版有譬如IP、日期、最大用戶數量的限制等。
而license控制的方法又有很多,目前比較流行,只要設計的好就很難破解的方法就是采用一對密匙(私匙加密公匙解密)來生成License文件中的Sinature簽名內容,再通過Base64或Hex來進行編碼。比如原BEA公司現在是Oracle公司的WebLogic就采用的是這種方法來設置License文件。
這里只進行一個比較簡單的實現:
一共三個類:
A.KeyGenerater類生成公鑰私鑰對
B.Signaturer類使用私鑰進行簽名
C.SignProvider類用公鑰驗證
公鑰和私鑰使用Base64加密Base64這個類很多地方都可以查到。
KeyGenerater類:
public class KeyGenerater {
private byte[] priKey;
private byte[] pubKey;
public void generater() {
try {
KeyPairGenerator keygen = KeyPairGenerator .getInstance("RSA");
SecureRandom secrand = new SecureRandom();
secrand.setSeed("www.川江號子.cn".getBytes()); // 初始化隨機產生器
keygen.initialize(1024, secrand);
KeyPair keys = keygen.genKeyPair();
PublicKey pubkey = keys.getPublic();
PrivateKey prikey = keys.getPrivate()
pubKey = Base64.encodeToByte(pubkey.getEncoded());
priKey = Base64.encodeToByte(prikey.getEncoded());
System.out.println("pubKey = " + new String(pubKey));
System.out.println("priKey = " + new String(priKey));
} catch (java.lang.Exception e) {
System.out.println("生成密鑰對失敗");
e.printStackTrace();
}
}
public byte[] getPriKey() {
return priKey;
}
public byte[] getPubKey() {
return pubKey;
}
}
Signaturer 類:
public class Signaturer {
public static byte[] sign(byte[] priKeyText, String plainText) {
try {
PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.decode(priKeyText));
KeyFactory keyf = KeyFactory.getInstance("RSA");
PrivateKey prikey = keyf.generatePrivate(priPKCS8);
// 用私鑰對信息生成數字簽名
Signature signet = java.security.Signature.getInstance("MD5withRSA");
signet.initSign(prikey);
signet.update(plainText.getBytes());
byte[] signed = Base64.encodeToByte(signet.sign());
return signed;
} catch (java.lang.Exception e) {
System.out.println("簽名失敗");
e.printStackTrace();
}
return null;
}
}
SignProvider 類:
public class SignProvider {
private SignProvider() {
}
public static boolean verify(byte[] pubKeyText, String plainText,
byte[] signText) {
try {
// 解密由base64編碼的公鑰,並構造X509EncodedKeySpec對象
X509EncodedKeySpec bobPubKeySpec = new X509EncodedKeySpec(Base64.decode(pubKeyText));
// RSA對稱加密算法
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
// 取公鑰匙對象
PublicKey pubKey = keyFactory.generatePublic(bobPubKeySpec);
// 解密由base64編碼的數字簽名
byte[] signed = Base64.decode(signText);
Signature signatureChecker = Signature.getInstance("MD5withRSA");
signatureChecker.initVerify(pubKey);
signatureChecker.update(plainText.getBytes());
// 驗證簽名是否正常
if (signatureChecker.verify(signed))
return true;
else
return false;
} catch (Throwable e) {
System.out.println("校驗簽名失敗");
e.printStackTrace();
return false;
}
}
}
