数字签名算法之RSA

数字签名算法之RSA

  • 1.数字签名简述
  • 2. 模型分析
  • 3. 代码实现
    • 3.1 签名算法实现
    • 3.2 测试代码
    • 3.3 运行结果

1.数字签名简述

数字签名算法可以看做是一种带有密钥的消息摘要算法,并且这种密钥包含了公钥和私钥。也就是说数字签名算法是非对称加密算法和消息摘要算法的结合体。

数字签名算法是公钥基础设施(PKI)以及许多网络安全机制(SSL/TLS、VPN等)的基础。

数字签名算法能够验证数据的完整性、认证性以及抗否认性。

数字签名算法遵循“私钥签名,公钥验证” 的签名/验证方式。

数字签名算法主要包括 RSA、DSA和ECDSA共3种算法。其中,RSA算法源于整数因子分解问题,DSA和ECDSA算法源于离散对数问题。

RSA既是加密/解密算法, 也是签名算法。

DSA只有签名算法,其基于DSS算法。

ECDSA算法是ECC算法与DSA算法的结合,想对于传统签名算法,具有速度快、强度高、签名短等优点,被广泛应用。

2. 模型分析

Alice作为发送方,Bob作为接收方,交互流程如下所示。
数字签名算法之RSA_第1张图片

3. 代码实现

Java与Bouncy Castle对RSA签名算法均有实现,具体细节如下表所示。

算法 密钥长度 密钥长度默认值 签名长度 备注
MD2withRSA、MD5withRSA、SHA1withRSA 512~65536位(密钥长度必须是64的倍数) 1024 与密钥长度相同 Java
SHA224withRSA、SHA256withRSA、SHA384withRSA、SHA512withRSA 、RIPEMD128withRSA、RIPEMD160withRSA 512~65536位(密钥长度必须是64的倍数) 2048 与密钥长度相同 Bouncy Castle实现

3.1 签名算法实现

下面是Java对RSA数字签名的实现


/**
     * 数字签名密钥算法
     */
    public static final String KEY_ALGORITHM = "RSA";

    /**
     * 数字签名
     * 签名/验证算法
     */
    public static final String SIGNATURE_ALGORITHM = "MD5withRSA";

    //公钥 Map Key
    private static final String PUBLIC_KEY = "RSAPublicKey";
    //私钥Map key
    private static final String PRIVATE_KEY = "RSAPrivateKey";

    /**
     * RSA密钥长度,默认1024位,密钥长度必须是64的倍数,范围512~65536位之间
     */
    private static final int KEY_SIZE = 512;
    
 public static byte[] sign(byte[] data, byte[] privateKey) throws Exception {
        //转换私钥材料
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKey);
        //实例化密钥工厂
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        //取私钥对象
        PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
        //实例化Signature
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        //初始化Signature
        signature.initSign(priKey);
        //更新
        signature.update(data);
        //签名
        return signature.sign();
    }

    public static boolean verity(byte[] data, byte[] publicKey, byte[] sign) throws  Exception{
        //转换公钥材料
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey);
        //实例化密钥工厂
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        //生成公钥
        PublicKey pubKey = keyFactory.generatePublic(keySpec);
        //实例化Signature
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        //初始化Signature
        signature.initVerify(pubKey);
        //更新
        signature.update(data);
        //校验证
        return signature.verify(sign);
    }

3.2 测试代码

 @Test
    public void rsaSignTest() throws Exception {
        //初始化密钥
        Map<String, Object> keyMap = RSACoder.initKey();
        byte[] publicKey = RSACoder.getPublicKey(keyMap);
        byte[] privateKey = RSACoder.getPrivateKey(keyMap);
        System.out.println("公钥:\n"+Base64.encodeToString(publicKey, Base64.DEFAULT));
        System.out.println("私钥:\n"+Base64.encodeToString(privateKey, Base64.DEFAULT));

        String inputStr = "RSA数字签名";
        byte[] data = inputStr.getBytes();
        //产生签名
        byte[] sign = RSACoder.sign(data, privateKey);
        System.out.println("签名:\t"+ Hex.toHexString(sign));
        //验证签名
        boolean status = RSACoder.verity(data, publicKey, sign);
        System.out.println("验签状态:\t"+ status);
        assertTrue(status);
    }

3.3 运行结果

2020-10-21 14:28:20.130 15667-15682/com.calvin.android.demo2 I/System.out: 公钥:
2020-10-21 14:28:20.130 15667-15682/com.calvin.android.demo2 I/System.out: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALVI158wtZj4N7Fhndfr0SxspYaoVJAYTcgR1czsgnTy
2020-10-21 14:28:20.130 15667-15682/com.calvin.android.demo2 I/System.out: Qz0cjuyVWqXFlxK3ZitLvuzuQqEKAHZkBSggBPxA660CAwEAAQ==
2020-10-21 14:28:20.130 15667-15682/com.calvin.android.demo2 I/System.out: 私钥:
2020-10-21 14:28:20.130 15667-15682/com.calvin.android.demo2 I/System.out: MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAtUjXnzC1mPg3sWGd1+vRLGylhqhU
2020-10-21 14:28:20.130 15667-15682/com.calvin.android.demo2 I/System.out: kBhNyBHVzOyCdPJDPRyO7JVapcWXErdmK0u+7O5CoQoAdmQFKCAE/EDrrQIDAQABAkEApjyaxXbE
2020-10-21 14:28:20.130 15667-15682/com.calvin.android.demo2 I/System.out: P/b2EynhtXugf61NiJLZoJ04zktUlCsZYiSu2V575e1uRahiv9Z9tO6otYbBQDb8DwtdjlgH0usw
2020-10-21 14:28:20.131 15667-15682/com.calvin.android.demo2 I/System.out: 4QIhANlMi777d9j+QVB1tw16FblEXm1YFBAW4WxAoAtFkM4ZAiEA1ZJD+A3wlhNLe5L9Zo9t7dHm
2020-10-21 14:28:20.131 15667-15682/com.calvin.android.demo2 I/System.out: qlrlyxDY5MOBq40XVLUCIFylfDeTM8f6r5JEfiVq1fRFqBTqprMtbjMfYp0rrc+RAiBPDGkt6fLv
2020-10-21 14:28:20.131 15667-15682/com.calvin.android.demo2 I/System.out: iUq5/WjfSh01FijbSvOc2qp82cQn+/vztQIhAIe/Rez3m7xmEzvL45IOVxfw7x0dwexDXdGdIIjo
2020-10-21 14:28:20.131 15667-15682/com.calvin.android.demo2 I/System.out: o9ak
2020-10-21 14:28:20.135 15667-15682/com.calvin.android.demo2 I/System.out: 签名:	612945943b56154cc6dce2bb13597ca734f6be79ea6e86191d34378271143a65405feeb9cbec9a1327166efa285ca117123a5bb26f0eb900e161b3ceb7b35224
2020-10-21 14:28:20.136 15667-15682/com.calvin.android.demo2 I/System.out: 验签状态:	true

你可能感兴趣的:(加密安全)