`

DSA数字签名

阅读更多

DSA数字签名,非对称加密的另一种实现。

    DSA

    DSA-Digital Signature Algorithm 是Schnorr和ElGamal签名算法的变种,被美国NIST作为DSS(DigitalSignature Standard)。简单的说,这是一种更高级的验证方式,用作数字签名。不单单只有公钥、私钥,还有数字签名。私钥加密生成数字签名,公钥验证数据及签名。如果数据和签名不匹配则认为验证失败!数字签名的作用就是校验数据在传输过程中不被修改。数字签名,是单向加密的升级!

    1.

 

    2.

 

    通过java代码实现如下:

  import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.interfaces.DSAPrivateKey;
import java.security.interfaces.DSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

/**
 * DSA安全编码组件
 *
 * @author 梁栋
 * @version 1.0
 * @since 1.0
 */
public abstract class DSACoder extends Coder {

    public static final String ALGORITHM = "DSA";

    /**
     * 默认密钥字节数
     *
     * <pre>
     * DSA
     * Default Keysize 1024
     * Keysize must be a multiple of 64, ranging from 512 to 1024 (inclusive).
     * </pre>
     */
    private static final int KEY_SIZE = 1024;

    /**
     * 默认种子
     */
    private static final String DEFAULT_SEED = "0f22507a10bbddd07d8a3082122966e3";

    private static final String PUBLIC_KEY = "DSAPublicKey";
    private static final String PRIVATE_KEY = "DSAPrivateKey";

    /**
     * 用私钥对信息生成数字签名
     *
     * @param data
     *            加密数据
     * @param privateKey
     *            私钥
     *
     * @return
     * @throws Exception
     */
    public static String sign(byte[] data, String privateKey) throws Exception {
        // 解密由base64编码的私钥
        byte[] keyBytes = decryptBASE64(privateKey);

        // 构造PKCS8EncodedKeySpec对象
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);

        // KEY_ALGORITHM 指定的加密算法
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);

        // 取私钥匙对象
        PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);

        // 用私钥对信息生成数字签名
        Signature signature = Signature.getInstance(keyFactory.getAlgorithm());
        signature.initSign(priKey);
        signature.update(data);

        return encryptBASE64(signature.sign());
    }

    /**
     * 校验数字签名
     *
     * @param data
     *            加密数据
     * @param publicKey
     *            公钥
     * @param sign
     *            数字签名
     *
     * @return 校验成功返回true 失败返回false
     * @throws Exception
     *
     */
    public static boolean verify(byte[] data, String publicKey, String sign)
            throws Exception {

        // 解密由base64编码的公钥
        byte[] keyBytes = decryptBASE64(publicKey);

        // 构造X509EncodedKeySpec对象
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);

        // ALGORITHM 指定的加密算法
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);

        // 取公钥匙对象
        PublicKey pubKey = keyFactory.generatePublic(keySpec);

        Signature signature = Signature.getInstance(keyFactory.getAlgorithm());
        signature.initVerify(pubKey);
        signature.update(data);

        // 验证签名是否正常
        return signature.verify(decryptBASE64(sign));
    }

    /**
     * 生成密钥
     *
     * @param seed
     *            种子
     * @return 密钥对象
     * @throws Exception
     */
    public static Map<String, Object> initKey(String seed) throws Exception {
        KeyPairGenerator keygen = KeyPairGenerator.getInstance(ALGORITHM);
        // 初始化随机产生器
        SecureRandom secureRandom = new SecureRandom();
        secureRandom.setSeed(seed.getBytes());
        keygen.initialize(KEY_SIZE, secureRandom);

        KeyPair keys = keygen.genKeyPair();

        DSAPublicKey publicKey = (DSAPublicKey) keys.getPublic();
        DSAPrivateKey privateKey = (DSAPrivateKey) keys.getPrivate();

        Map<String, Object> map = new HashMap<String, Object>(2);
        map.put(PUBLIC_KEY, publicKey);
        map.put(PRIVATE_KEY, privateKey);

        return map;
    }

    /**
     * 默认生成密钥
     *
     * @return 密钥对象
     * @throws Exception
     */
    public static Map<String, Object> initKey() throws Exception {
        return initKey(DEFAULT_SEED);
    }

    /**
     * 取得私钥
     *
     * @param keyMap
     * @return
     * @throws Exception
     */
    public static String getPrivateKey(Map<String, Object> keyMap)
            throws Exception {
        Key key = (Key) keyMap.get(PRIVATE_KEY);

        return encryptBASE64(key.getEncoded());
    }

    /**
     * 取得公钥
     *
     * @param keyMap
     * @return
     * @throws Exception
     */
    public static String getPublicKey(Map<String, Object> keyMap)
            throws Exception {
        Key key = (Key) keyMap.get(PUBLIC_KEY);

        return encryptBASE64(key.getEncoded());
    }
}

 

  再给出一个测试类:

  import static org.junit.Assert.*;

import java.util.Map;

import org.junit.Test;

/**
 *
 * @author 梁栋
 * @version 1.0
 * @since 1.0
 */
public class DSACoderTest {

    @Test
    public void test() throws Exception {
        String inputStr = "abc";
        byte[] data = inputStr.getBytes();

        // 构建密钥
        Map<String, Object> keyMap = DSACoder.initKey();

        // 获得密钥
        String publicKey = DSACoder.getPublicKey(keyMap);
        String privateKey = DSACoder.getPrivateKey(keyMap);

        System.err.println("公钥:\r" + publicKey);
        System.err.println("私钥:\r" + privateKey);

        // 产生签名
        String sign = DSACoder.sign(data, privateKey);
        System.err.println("签名:\r" + sign);

        // 验证签名
        boolean status = DSACoder.verify(data, publicKey, sign);
        System.err.println("状态:\r" + status);
        assertTrue(status);

    }

}

    控制台输出:

 公钥:
MIIBtzCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZp
RV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fn
xqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuE
C/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJ
FnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImo
g9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYQAAoGAIu4RUlcQLp49PI0MrbssOY+3uySVnp0TULSv
5T4VaHoKzsLHgGTrwOvsGA+V3yCNl2WDu3D84bSLF7liTWgOj+SMOEaPk4VyRTlLXZWGPsf1Mfd9
21XAbMeVyKDSHHVGbMjBScajf3bXooYQMlyoHiOt/WrCo+mv7efstMM0PGo=

私钥:
MIIBTAIBADCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2
USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4
O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmC
ouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCB
gLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhR
kImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoEFwIVAIegLUtmm2oQKQJTOiLugHTSjl/q

签名:
MC0CFQCMg0J/uZmF8GuRpr3TNq48w60nDwIUJCyYNah+HtbU6NcQfy8Ac6LeLQs=

状态:
true

 

分享到:
评论

相关推荐

    dsa数字签名算法的验证及实现

    总的来说,DSA数字签名算法是网络安全和信息安全的关键组成部分,它通过数学原理确保了数据的完整性和非否认性。理解和掌握DSA的实现与验证方法对于任何从事安全相关工作的IT专业人员来说都是至关重要的。

    DSA数字签名 DSA数字签名

    DSA数字签 DSA数字签DSA数字签名 DSA数字签名

    DSA数字签名例子

    在电子通信和互联网交易中,DSA数字签名被广泛用于确保数据的完整性和发送者的身份验证。 DSA的核心原理是利用非对称加密技术,即每个用户有一对密钥,一个是私钥,仅由用户自己保管,用于签名;另一个是公钥,可以...

    DSA.zip_DSA C数字签名_DSA 签名_DSA签名_dsa_dsa 数字签名

    在提供的压缩包文件中,"DSA数字签名"可能包含了实现这些功能的源代码,这将帮助开发者理解DSA算法的实现细节,学习如何在C语言环境下实现数字签名。这些源代码可能包括了DSA算法的实现函数,如计算签名、验证签名的...

    DSA.zip_DSA C数字签名_DSA数字签名_DSA签名_c 数字签名_数字签名

    DSA数字签名广泛应用于电子商务、网络安全、软件授权、文件完整性校验等领域,如HTTPS协议中的SSL/TLS证书、Git版本控制系统的提交验证等。 总的来说,`DSA.zip`文件提供的`DSA.CPP`源代码可能是一个实用的工具,...

    DSA.rar_DSA数字签名_DSA算法_dsa_java dsa_数字签名

    总结起来,DSA数字签名在Java中的实现涉及了密钥对生成、签名生成与验证等步骤,这些步骤都是通过`java.security`包中的类和方法完成的。了解并掌握这些知识点,对于开发安全的网络应用程序至关重要。同时,通过阅读...

    dsa.rar_DSA C数字签名_DSA签名_dsa_dsa 数字签名_数字签名DSA

    总结,DSA数字签名算法是现代网络安全的重要组成部分,结合MD5或SHA-1等哈希函数,为数据提供了可靠的完整性保护和身份验证。在C语言环境中实现DSA签名,不仅需要理解算法原理,还需要熟悉文件操作和可能涉及的加密...

    md5.zip_DSA C数字签名_DSA 签名_DSA实现_Stankiewicz_dsa 数字签名

    《深入理解DSA数字签名:C语言实现与SHA哈希算法》 数字签名是现代密码学中的重要组成部分,它在确保信息安全传输、防止篡改和伪造等方面发挥着关键作用。DSA(Digital Signature Algorithm)是由美国国家标准和...

    DSA数字签名算法

    我不知道是这个DSA算法本身有问题还是什么.验证签名这块也有问题

    DSA数字签名算法.pdf

    DSA数字签名算法 DSA(Digital Signature Algorithm,数字签名算法)是一种公开密钥算法,用作数字签名标准的一部分。它不能用作加密,只用作数字签名。DSA 使用公开密钥,为接受者验证数据的完整性和数据发送者的...

    DSA数字签名算法.doc

    DSA数字签名算法 DSA数字签名算法是数字签名标准的一部分,它使用公开密钥算法,不能用作加密,只用作数字签名。DSA算法的安全性基于解离散对数的困难性,这类签字标准具有较大的兼容性和适用性,成为网络安全体系...

    DSA 数字签名 /C++/源代码

    学习DSA数字签名不仅有助于理解公钥密码学的基本原理,而且对于开发涉及安全通信的应用程序至关重要。通过阅读和分析提供的源代码,可以加深对这个过程的理解,同时提高编程技能。在实际项目中,还可以结合其他安全...

    实验三 DSA数字签名算法.doc

    DSA 数字签名算法 数字签名是数据在公开行信道中传输的安全保障,能够实现数据的公开、公正、不可抵赖等特点的方法。DSA(Digital Signature Algorithm)是 Schnorr 和 ElGamal 算法的变种,被美国国家标准技术研究...

    DSA数字签名实验原理.pdf

    DSA数字签名的使用确保了消息的完整性和发送者的身份认证,广泛应用于电子商务、电子合同、软件授权等领域。由于其安全性基于计算离散对数的难度,随着计算能力的提升,可能会出现安全性挑战,因此NIST后来增加了...

    dsa.zip_DSA C数字签名_c++实现dsa_dsa_数字签名_签名

    在C++中实现DSA数字签名涉及到以下几个关键步骤: 1. **密钥生成**:DSA需要一对密钥,包括一个私钥和一个公钥。私钥用于签名,公钥用于验证。首先选择两个大素数p和q,计算它们的乘积n=p*q,并找到一个满足1 且gcd...

    DSA签名算法的C#实现

    DSA(Digital Signature Algorithm)是一种基于离散对数问题的公钥密码学算法,常用于数字签名,以确保数据的完整性和发送者的身份。在C#中实现DSA签名算法,主要涉及以下几个关键步骤和知识点: 1. **密钥生成**:...

    RSA.rar_C++_dsa_dsa 数字签名_rsa_rsa 签名

    在IT领域,尤其是在网络安全和密码学中,RSA和DSA(Digital Signature Algorithm)是两种重要的公钥加密算法,常用于数字签名。数字签名是确保数据完整性和发送者身份验证的关键技术,而C++作为一门强大的系统级编程...

Global site tag (gtag.js) - Google Analytics