数字签名算法

RSA、DSA和ECDSA三种算法。
通常是先对消息做摘要处理,然后使用私钥对摘要值进行签名处理;验证时,使用公钥验证消息的摘要值。

public class RSASin {
       
        private static final String KEY_ALGORITHM= "RSA";
       
        public static final String SIGNATURE_ALGORITHM= "MD5WithRSA";
       
        private static final String PUBLIC_KEY= "RSAPublicKey";
        private static final String PRIVATE_KEY= "RSAPrivateKey";
        private static final int KEY_SIZE=512;
       
        private static byte[] pubKey;
        private static byte[] priKey;
       
        //数字签名,根据私钥获取数字签名
        public static byte[] sign(byte[] data, byte[] privateKey) throws Exception{
               //私钥规范
              PKCS8EncodedKeySpec pkcs8= new PKCS8EncodedKeySpec(privateKey);
               //密钥工厂
              KeyFactory keyFac=KeyFactory. getInstance(KEY_ALGORITHM);
              PrivateKey priKey=keyFac.generatePrivate(pkcs8);
               //实例化Signature
              Signature signature=Signature. getInstance(SIGNATURE_ALGORITHM);
               //初始化
              signature.initSign(priKey);
               //更新
              signature.update(data); //根据数据更新签名
               //签名
               return signature.sign();
       }
       
       
        //校验--公钥验证
        public static boolean verify(byte[] data, byte[] publicKey,byte[] sign) throws Exception{
               //公钥规范
              X509EncodedKeySpec x509= new X509EncodedKeySpec(publicKey);
              KeyFactory keyFac=KeyFactory. getInstance(KEY_ALGORITHM);
               //生成公钥
              PublicKey pubKey=keyFac.generatePublic(x509);
              
              Signature signature=Signature. getInstance(SIGNATURE_ALGORITHM);
              signature.initVerify(pubKey);
              signature.update(data);
               //验证
               return signature.verify(sign);
       }
       
        //取得私钥
        public static byte[] getPrivateKey(Map<String,Object> keyMap){
              Key key=(Key) keyMap.get( PRIVATE_KEY);
               return key.getEncoded();
       }
       
        //公钥
        public static byte[] getPublicKey(Map<String,Object> keyMap){
              Key key=(Key)keyMap.get( PUBLIC_KEY);
               return key.getEncoded();
       }
       
        //初始化密钥对
        public static Map<String,Object> initKey() throws Exception{
              KeyPairGenerator keyPairGen=KeyPairGenerator.getInstance( KEY_ALGORITHM);
              keyPairGen.initialize( KEY_SIZE);
               //生成密钥对
              KeyPair keyP=keyPairGen.generateKeyPair();
               //公钥
              RSAPublicKey publicKey=(RSAPublicKey)keyP.getPublic();
               //私钥
              RSAPrivateKey privateKey=(RSAPrivateKey)keyP.getPrivate();
               //封装密钥
              Map<String,Object> keyMap= new HashMap<String,Object>(2);
              keyMap.put( PRIVATE_KEY, (Object) privateKey);
              keyMap.put( PUBLIC_KEY, (Object) publicKey);
               return keyMap;
       }
       
        public static final void main(String[] args) throws Exception{
              Map<String,Object> kMap= initKey();
               pubKey=getPublicKey(kMap);
               priKey=getPrivateKey(kMap);
              System. err.println("公钥:\n" +Base64.encodeBase64String (pubKey ));
              System. err.println("私钥:\n" +Base64.encodeBase64String (priKey ));
              
              String str= "RSA数字签名" ;
               byte[] data=str.getBytes();
              
               //产生签名
               byte[] sign=sign(data, priKey);
              System. err.println("签名:\n" +Hex.encodeHexString (sign));
              
               //验证签名
               boolean status=verify(data, pubKey, sign);
              System. err.println("状态:\n" +status);
              
               //验证
               assertTrue(status);
       }
}
posted @ 2014-08-30 11:19  徐小鱼  阅读(1055)  评论(0编辑  收藏  举报