深入理解数字签名原理与技术

论坛 期权论坛 期权     
薛勤的博客   2019-10-27 05:54   2389   0
点击上方“蓝色字体”,选择“置顶公众号”

技术文章第一时间送达!

在腾讯工作已经第三周了,由于是支付业务,不免会涉及到加解密、数字签名之类的安全手段,花了一天时间,学习了下数字签名,整理发出。
[h1]1.数字签名概述[/h1]在讨论数字签名之前,我们先来说说签名。签名,即自己写自己的名字,尤其为表示同意、认可、承担责任或义务。在实际生活中,一些方式(如字迹,指纹等)一直被用作签名者身份的证明。这是因为:签名是可信的;不可伪造的;不可重用的;不可抵赖的。签名即代表着同意,并产生法律效力,在法律上赋予了文件以真实性。
在日渐来临的数字化生活中,由于信息在存储,传输和处理等过程往往是在开放的通信网络上进行的,所以信息更容易受到来自外界或内部的窃听、截取、修改、伪造和重放等多种手段的攻击。这时候,就需要数字签名来保证消息的来源、消息的真实,并确保消息发送者不可以抵赖自己发送的消息,其与现实生活中签名的作用大致相同。
[h1]2.数字签名性质[/h1]数字签名作为一种密码技术,具有以下功能和性质:
1.防冒充
其他人不能伪造对消息的签名,因为私有密钥只有签名者自己知道,所以其他人不能伪造出正确的签名结果。要求私钥的持有人保存好自己的私钥。
2.防篡改
对于数字签名,签名和原有文件己经形成一个混合的整体数据,不能篡改,从而保证了数据的完整性。
3.防重放
在数字签名中,如果采用了对签名报文添加流水号、时戳等技术,可以防止重放攻击.
4.防抵赖
数字签名可以鉴别身份,不可能冒充伪造。签名者无法对自己做过的签名抵赖。要防止接收者的抵赖,在数字签名体制中,要求接收者返回一个自己签名的表示收到的报文,给对方或者是第三方,或者引入第三方仲裁机制。这样,双方均不可抵赖。
5.机密性
有了机密性的保证,截取攻击就不会成功了。对要签名的消息进行适合的加密操作来保证机密性,这些涉及到加密或签密理论。
[h1]3.对称加密和非对称加密[/h1]在学习数字签名的工作原理之前,需要了解对称加密和非对称加密的原理。
对称加密
所谓对称加密,是采用对称密码编码技术的加密措施,它的特点是文件加密和解密都是使用相同的密钥。
这种方法在密码学中叫做对称加密算法,对称加密算法使用起来简单快捷,密钥较短,且破译困难,除了数据加密标准(DES),另一个对称密钥加密系统是国际数据加密算法(IDEA),它比DES的加密性好,而且对计算机功能要求也没有那么高。
非对称加密
与对称加密算法不同,非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(privatekey)。
公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。
因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。
[h1]4.信息摘要[/h1]一般在进行数字签名时,需要先对文件使用HASH算法计算其信息摘要,然后对该摘要值进行数字签名。
信息摘要:对数据进行处理,得到一段固定长度的结果,其特点:
1、输出长度固定。即输出长度和输入长度无关。
2、不可逆。即由输出数据理论上不能推导出输入数据
4、对输入数据敏感。当输入数据变化极小时,输出数据也会发生明显的变化
5、防碰撞。即不同的数据数据得到相同输出数据的可能性极低。
由于信息摘要具有上述特点,一般保证数据的完整性,对一个大文件进行摘要运算,得到其摘要值。通过网络或者其他渠道传输后,通过验证其摘要值,确定大文件本身有没有发生变化。
[h1]5.数字签名原理[/h1]数字签名实现的具体原理:
1.将报文按双方约定的HASH算法计算得到一个固定位数的报文摘要。在数学上保证,只要改动报文中任何一位,重新计算出的报文摘要值就会与原先的值不相符。这样就保证了报文的不可更改性。
2.将该报文摘要值用发送者的私人密钥加密即称数字签名,然后连同原报文和数字证书(包含公钥)一起发送给接收者。
3.接收方收到数字签名后,用同样的HASH算法对报文计算摘要值,然后将数字签名用发送者的公钥进行解密,并与报文摘要值相比较,如相等则说明报文确实来自所称的发送者。
上述过程可以借用下图完美诠释:


为了防止公钥在传输过程中被调包,需要证书中心(简称CA)为公钥做认证。证书中心用自己的私钥,对公钥和一些相关信息一起加密,生成"数字证书"(Digital Certificate),客户端用CA的公钥解开数字证书,从而保证公钥的真实性。
[h1]5.数字签名算法—RSA[/h1]RSA是目前计算机密码学中最经典算法,也是目前为止使用最广泛的数字签名算法,RSA数字签名算法的密钥实现与RSA的加密算法是一样的,算法的名称都叫RSA。密钥的产生和转换都是一样的,包括在售的所有SSL数字证书、代码签名证书、文档签名以及邮件签名大多都采用RSA算法进行加密。
RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的绝大多数密码攻击,已被ISO推荐为公钥数据加密标准。
RSA数字签名算法主要包括MD和SHA两种算法,例如我们熟知的MD5和SHA-256即是这两种算法中的一类,具体如下表格分布:


示例代码:
[code]import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

public class HelloRSA {

    private final static String SIGNATURE_ALGORITHM = "RSA";
    private final static String KEY_ALGORITHM = "SHA256withRSA"; // MD5withRSA
    private final static String src = "Hello World";

    public static void main(String[] args) {
        jdkRSA();
    }

    public static void jdkRSA() {
        try {
            //1.初始化密钥
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(SIGNATURE_ALGORITHM);
            keyPairGenerator.initialize(512); // 位(64的整数倍)
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            RSAPublicKey rsaPublicKey = (RSAPublicKey)keyPair.getPublic(); //公钥
            RSAPrivateKey rsaPrivateKey = (RSAPrivateKey)keyPair.getPrivate(); //私钥

            //2.执行签名
            //PKCS8EncodedKeySpec类表示私钥的ASN.1编码。
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
            KeyFactory keyFactory = KeyFactory.getInstance(SIGNATURE_ALGORITHM);
            PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
            //签名
            Signature signature = Signature.getInstance(KEY_ALGORITHM);
            signature.initSign(privateKey);
            signature.update(src.getBytes());
            byte[] result = signature.sign();
            System.out.println("jdk "+SIGNATURE_ALGORITHM+" sign : " + bytesToHexString(result));

            //3.验证签名
            //X509EncodedKeySpec类表示根据ASN.1类型SubjectPublicKeyInfo编码的公钥的ASN.1编码。
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
            keyFactory = KeyFactory.getInstance(SIGNATURE_ALGORITHM);
            PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
            //验签
            signature = Signature.getInstance(KEY_ALGORITHM);
            signature.initVerify(publicKey);
            signature.update(src.getBytes());
            boolean bool = signature.verify(result);
            System.out.println("jdk "+SIGNATURE_ALGORITHM+" verify : " + bool);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * byte[] 转 16进制
     */
    private static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder();
        if (src == null || src.length
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:
帖子:
精华:
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP