public abstract class MyRSACoder { public static final String KEY_ALGORITHM = "RSA"; public static final String KEY_PROVIDER = "BC"; public static final String SIGNATURE_ALGORITHM = "SHA1WithRSA"; /** * 初始化密钥对 */ public static MapinitKeys(String seed) throws Exception { Map keyMap = new HashMap (); Security.addProvider(new BouncyCastleProvider()); KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM,KEY_PROVIDER); keyPairGenerator.initialize(1024,new SecureRandom(seed.getBytes())); KeyPair pair = keyPairGenerator.generateKeyPair(); RSAPublicKey rsaPublicKey = (RSAPublicKey) pair.getPublic(); RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) pair.getPrivate(); KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM,KEY_PROVIDER); RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger(rsaPublicKey.getModulus().toString()),new BigInteger(rsaPublicKey.getPublicExponent().toString())); RSAPrivateKeySpec priKeySpec = new RSAPrivateKeySpec(new BigInteger(rsaPrivateKey.getModulus().toString()),new BigInteger(rsaPrivateKey.getPrivateExponent().toString())); PublicKey publicKey = factory.generatePublic(pubKeySpec); PrivateKey privateKey = factory.generatePrivate(priKeySpec); System.out.println("公钥:" + pubKeySpec.getModulus() + "----" + pubKeySpec.getPublicExponent()); System.out.println("私钥:" + priKeySpec.getModulus() + "----" + priKeySpec.getPrivateExponent()); keyMap.put("publicKey", publicKey); keyMap.put("privateKey", privateKey); return keyMap; } /** * 私钥加密 * */ public static byte[] encryptRSA(byte[] data,PrivateKey privateKey) throws Exception { Cipher cipher = Cipher.getInstance(KEY_ALGORITHM,KEY_PROVIDER); cipher.init(Cipher.ENCRYPT_MODE, privateKey); int dataSize = cipher.getOutputSize(data.length); int blockSize = cipher.getBlockSize(); int blockNum = 0; if (data.length % blockSize == 0) { blockNum = data.length / blockSize; } else { blockNum = data.length / blockSize + 1; } byte[] raw = new byte[dataSize * blockNum]; int i = 0; while (data.length - i * blockSize > 0) { if (data.length - i * blockSize > blockSize) { cipher.doFinal(data, i * blockSize, blockSize, raw, i * dataSize); } else { cipher.doFinal(data, i * blockSize, data.length - i * blockSize, raw, i * dataSize); } i++; } return raw; } /** * 生成数字签名 * */ public static String sign(byte[] encoderData,PrivateKey privateKey) throws Exception { Signature sig = Signature.getInstance(SIGNATURE_ALGORITHM,KEY_PROVIDER); sig.initSign(privateKey); sig.update(encoderData); return new String(Base64.encode(sig.sign())); } /** * 校验数字签名 * */ public static boolean verify (byte[] encoderData,String sign,PublicKey publicKey) throws Exception { Signature sig = Signature.getInstance(SIGNATURE_ALGORITHM,KEY_PROVIDER); sig.initVerify(publicKey); sig.update(encoderData); return sig.verify(Base64.decode(sign)); }
main
public class MyRSACoderTest { public static void main(String[] args) throws Exception { MapkeyMap = MyRSACoder.initKeys("0"); PublicKey publicKey = (PublicKey) keyMap.get("publicKey"); PrivateKey privateKey = (PrivateKey) keyMap.get("privateKey"); String str = "您好!"; byte[] encoderData = MyRSACoder.encryptRSA(str.getBytes(), privateKey); String sign = MyRSACoder.sign(encoderData, privateKey); boolean status = MyRSACoder.verify(encoderData, sign, publicKey); System.out.println("原文:" + str); System.out.println("密文:" + new String(encoderData)); System.out.println("签名:" + sign); System.out.println("验证结果:" + status); } }
java中使用公钥加密私钥解密原理实现license控制
现在很多J2EE应用都采用一个license文件来授权系统的使用,特别是在系统购买的早期,会提供有限制的license文件对系统进行限制,比如试用版有譬如IP、日期、最大用户数量的限制等。而license控制的方法又有很多,目前比较流行,只要设计的好就很难破解的方法就是采用一对密匙(私匙加密公匙解密)来生成License文件中的Sinature签名内容,再通过Base64或Hex来进行编码。比如原BEA公司现在是Oracle公司的WebLogic就采用的是这种方法来设置License文件。
这里只进行一个比较简单的实现:
一共三个类:
A.KeyGenerater类生成公钥私钥对
B.Signaturer类使用私钥进行签名
C.SignProvider类用公钥验证