• 技术文章 >常见问题

    常用数字签名算法是什么

    尚2019-12-21 11:34:27原创3635

    数字签名是一个带有密钥的消息摘要算法,这个密钥包括了公钥和私钥,用于验证数据完整性、认证数据来源和抗否认,遵循OSI参考模型、私钥签名和公钥验证。也是非对称加密算法和消息摘要算法的结合体,常见的数字签名算法主要有RSA、DSA、ECDSA三种。

    RSA是目前计算机密码学中最经典算法,也是目前为止使用最广泛的数字签名算法,RSA数字签名算法的密钥实现与RSA的加密算法是一样的,算法的名称都叫RSA。

    它的消息传递操作是:

    1、由消息发送方构建密匙对,

    2、由消息发送的一方公布公钥至消息接收方,

    3、消息发送方对消息用私钥做签名处理

    4、消息接收方用公钥对消息做验证

    RSA的数字签名代码实现:

    DSA签名实现类似,ECDSA实现相比前两者在密匙对成功的方式上存在差别。

    import org.apache.commons.codec.binary.Base64;
    
    import java.security.*;
    import java.security.interfaces.RSAPrivateKey;
    import java.security.interfaces.RSAPublicKey;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;
    import java.util.HashMap;
    import java.util.Map;
    
    public class RSASignature {
    
        private static final String KEY_ALGORITHM="RSA";
        private static final String SIGNATURE_ALGORITHM="MD5withRSA";
        private static final String PUBLIC_KEY="RSAPublicKey";
        private static final String PRIVATE_KEY="RSAPrivateKey";
        /**
         * RSA密匙长度,默认是1024位,密匙长度必须是在64的倍数
         * 范围是512--65536之间
         *
         */
        private static final int KEY_SIZE = 512;
    
        public static void main(String[] args) throws Exception {
    
            String str = "hello vison";
            Map<String, Object> map = initKey();
            byte[] privateKey = getPrivateKey(map);
            //签名
            byte[] signData = sign(str.getBytes(), privateKey);
            System.out.println("signData: " + Base64.encodeBase64(signData));
            //校验
            byte[] pulicKey = getPulicKey(map);
            boolean status = verify(str.getBytes(), pulicKey, signData);
            System.out.println("verify result: " + status);
    
        }
    
        /**
         *
         * @param data 待校验的数据
         * @param key 公钥
         * @param sign 数据签名
         * @return boolean 校验成功返回true,否则返回false
         * @throws Exception
         */
        public static boolean verify(byte[] data,byte[] key,byte[] sign)throws Exception{
            //获取公钥
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(key);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
            //校验数据
            Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
            signature.initVerify(publicKey);
            signature.update(data);
            return signature.verify(sign);
        }
        /**
         * 私钥签名
         * @param data 待签名数据
         * @param key 私钥
         * @return byte[] 加密数据
         * @throws Exception
         */
        public static byte[] sign(byte[] data,byte[] key) throws Exception {
            //获取私钥
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(key);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
            //签名
            Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
            signature.initSign(privateKey);
            signature.update(data);
            return signature.sign();
        }
        /**
         * 获取私钥
         * @param keyMap
         * @return
         */
        public static byte[] getPrivateKey(Map<String,Object> keyMap){
            Key key = (Key) keyMap.get(PRIVATE_KEY);
            return key.getEncoded();
        }
        /**
         * 获取公钥
         * @param keyMap
         * @return
         */
        public static byte[] getPulicKey(Map<String,Object> keyMap){
            Key key = (Key) keyMap.get(PUBLIC_KEY);
            return key.getEncoded();
    
        }
        /**
         * 初始化密匙对
         * @return Map 密钥map
         * @throws Exception
         */
        public static Map<String,Object> initKey() throws Exception {
            //实例化密钥对生成器
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
            //初始化
            keyPairGenerator.initialize(KEY_SIZE);
            //生成密匙对
            KeyPair keyPair = keyPairGenerator.genKeyPair();
            //私钥
            RSAPrivateKey privateKey = (RSAPrivateKey)keyPair.getPrivate();
            //公钥
            RSAPublicKey publicKey = (RSAPublicKey)keyPair.getPublic();
            //封装密钥
            HashMap<String, Object> map = new HashMap<>(2);
            map.put(PUBLIC_KEY,publicKey);
            map.put(PRIVATE_KEY,privateKey);
            return map;
        }
    }

    以上就是常用数字签名算法是什么的详细内容,更多请关注php中文网其它相关文章!

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    专题推荐:数字签名算法
    上一篇:wifi无线上网中毒了怎么办 下一篇:主板和机箱要装铜柱吗

    相关文章推荐

    • PHP 进程池与轮询调度算法实现多任务• PHPCMS漏洞之authkey生成算法问题导致authkey泄露• 快速掌握java排序算法-快速排序(图文)• 一个递归算法必须包括什么

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网