Rumah  >  Artikel  >  常用数字签名算法是什么

常用数字签名算法是什么

尚
asal
2019-12-21 11:34:277739semak imbas

常用数字签名算法是什么

数字签名是一个带有密钥的消息摘要算法,这个密钥包括了公钥和私钥,用于验证数据完整性、认证数据来源和抗否认,遵循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;
    }
}

Atas ialah kandungan terperinci 常用数字签名算法是什么. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn