我对于在Java的Web项目中Liscense认证的一些想法

最近尝试调查一些Java的web项目的Liscense认证,网上众说纷纭,在参考了一些资料以后,分享一下我的想法。
首先,需要理解数字证书的原理,下面这篇文章写得很不错:
数字证书原理

我觉得单机认证不是很靠谱,既然是web项目,那肯定能联网,所以可以用网上认证的方式做。

Liscense认证流程图:


Liscense连接数认证(比方说某个Liscense只允许500人同时登录):


ActiveSessionCounter(需在web.xml中插入个Listener):

package com.sun.liscense;


import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;


public class ActiveSessionCounter implements HttpSessionListener {


/*    
 * 在web.xml中加入以下代码
 * 
 * <listener>
	    <listener-class>com.sun.liscense.ActiveSessionCounter</listener-class>
	</listener>
 */


    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        System.out.println("session 创建了,人数+1");httpSessionEvent.getSession().getServletContext();
    }


    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        HttpSession httpSession=httpSessionEvent.getSession();
        System.out.println("session"+httpSession.getId()+" 销毁了,人数-1");
    }


}

加解密采用RSA加密的方式,这个比较简单,网上找了段加解密的代码。

RSAModule:
/**
 * @author Administrator
 *
 */
package com.sun.liscense;

import java.math.BigInteger;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.Cipher;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import com.sun.jersey.core.util.Base64;

public abstract class RSAModule {
    public static final String KEY_ALGORITHM = "RSA";
    public static final String KEY_PROVIDER = "BC";
    public static final String SIGNATURE_ALGORITHM = "SHA1WithRSA";
 
    /**
     * 初始化密钥对
     */
    public static Map<String, Object> initKeys(String seed) throws Exception {
         
        Map<String, Object> keyMap = new HashMap<String, Object>();
        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));
    }
}

RSAService(加解密及验证方法的调用):
package com.sun.liscense;

import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Map;

public class RSAService {
 
    public static void main(String[] args) throws Exception {
         
        Map<String, Object> keyMap = RSAModule.initKeys("0");
        PublicKey publicKey = (PublicKey) keyMap.get("publicKey");
        PrivateKey privateKey = (PrivateKey) keyMap.get("privateKey");
         
        String str = "这是原文";
        byte[] encoderData = RSAModule.encryptRSA(str.getBytes(), privateKey);
        String sign = RSAModule.sign(encoderData, privateKey);
        boolean status = RSAModule.verify(encoderData, sign, publicKey);
         
        System.out.println("原文:" + str);
        System.out.println("密文:" + new String(encoderData));
        System.out.println("签名:" + sign);
        System.out.println("验证结果:" + status);
    }
}


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值