数字签名标准算法——DSA

it2024-08-11  36

数字签名标准算法——DSA

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

1. 算法简述

RSA为经典数字签名算法 数字签名标准(Digital Signature Standard, DSS), DSS本质是ElGamal数字签名算法,DSS使用的算法成为数字签名算法(Digital Signature Algorithm, DSA)。

DSA与RSA是数字证书不可或缺的两种算法。DSA算法仅包含数字签名算法,使用DSA算法的数字证书无法进行加密通信,而RSA算法既包含加密/解密算法,同时兼具数字签名算法。

2.模型分析

Alice与Bob作为消息交互双方,签名/验签流程如下

3. 代码实现

Java及Bouncy Castle对RSA实现细节

算法密钥长度密钥默认长度签名长度备注SHA1withDSA512~1024位(64倍数)1024-JavaSHA224withDSA、SHA256withDSA 、SHA384withDSA、SHA512withDSA512~1024位(64倍数)1024-Bouncy Castle实现

3.1 算法实现

下面是Java的DSA算法实现

package com.calvin.android.demo2.secrity; 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; /** * Author:cl * Email:lhzheng@grandstream.cn * Date:20-10-21 */ public class DSACoder { /** * 数字签名密钥算法 */ public static final String KEY_ALGORITHM = "DSA"; /** * 数字签名 * 签名/验证算法 */ public static final String SIGNATURE_ALGORITHM = "SHA1withDSA"; //公钥 Map Key private static final String PUBLIC_KEY = "DSAPublicKey"; //私钥Map key private static final String PRIVATE_KEY = "DSAPrivateKey"; /** * DSA密钥长度,默认1024位,密钥长度必须是64的倍数,范围512~1024位之间 */ private static final int KEY_SIZE = 1024; /** * 签名 * @param data 待签名数据 * @param privateKey 私钥 * @return byte[] 数字签名 * @throws Exception 异常 */ 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(); } /** * 校验 * @param data 待校验数据 * @param publicKey 公钥 * @param sign 数字签名 * @return boolean 校验成功返回true,校验失败返回false * @throws Exception */ 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); } public static Map<String, Object> initKey() throws Exception { //实例化密钥对生成器 KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM); //初始化密钥对生成器 keyPairGen.initialize(KEY_SIZE, new SecureRandom()); //生成密钥对 KeyPair keyPair = keyPairGen.generateKeyPair(); //公钥 DSAPublicKey publicKey = (DSAPublicKey)keyPair.getPublic(); //私钥 DSAPrivateKey privateKey = (DSAPrivateKey)keyPair.getPrivate(); //封装密钥 Map<String, Object> keyMap = new HashMap<>(2); keyMap.put(PUBLIC_KEY, publicKey); keyMap.put(PRIVATE_KEY, privateKey); return keyMap; } public static byte[] getPublicKey(Map<String, Object> keyMap){ return ((Key)keyMap.get(PUBLIC_KEY)).getEncoded(); } public static byte[] getPrivateKey(Map<String, Object> keyMap){ return ((Key)keyMap.get(PRIVATE_KEY)).getEncoded(); } }

3.2 测试代码

@Test public void dsaSignTest() throws Exception { //初始化密钥 Map<String, Object> keyMap = DSACoder.initKey(); byte[] publicKey = DSACoder.getPublicKey(keyMap); byte[] privateKey = DSACoder.getPrivateKey(keyMap); System.out.println("公钥:\t"+Base64.encodeToString(publicKey, Base64.DEFAULT)); System.out.println("私钥:\t"+Base64.encodeToString(privateKey, Base64.DEFAULT)); String inputStr = "DSA数字签名"; byte[] data = inputStr.getBytes(); //产生签名 byte[] sign = DSACoder.sign(data, privateKey); System.out.println("签名:\t"+ Hex.toHexString(sign)); //验证签名 boolean status = DSACoder.verity(data, publicKey, sign); System.out.println("验签状态:\t"+ status); assertTrue(status); }

3.3 运行结果

2020-10-21 15:06:08.630 15896-15911/com.calvin.android.demo2 I/System.out: 公钥: MIIBtjCCASsGByqGSM44BAEwggEeAoGBALp0XqBwHX0xv8pzTPn1vYI9xC5eshO2gPWPXOhjNSWY 2020-10-21 15:06:08.630 15896-15911/com.calvin.android.demo2 I/System.out: El4u3aLJcOWW9zrvb9Zzm6jjH316keUqnhbd1A007N3sXIW43YVjsPcqQLw5g45PTxK83UPsVGck 2020-10-21 15:06:08.630 15896-15911/com.calvin.android.demo2 I/System.out: ucwOx38Z1ByI0HW/Hgt8ym3GZ6YRsBNFoJ6AV7ECbHeg9FQ/XvhTAhUAoCMUYSx3rXCqIs7ykNak 2020-10-21 15:06:08.630 15896-15911/com.calvin.android.demo2 I/System.out: JapM0G0CgYBo66ouj4XZz0S3FQaoknrOuSxlYj0UidiXx3NjqEwzSf6gUEVRur+O+xee0pIZ7Ywf 2020-10-21 15:06:08.630 15896-15911/com.calvin.android.demo2 I/System.out: wzGfUqjP+Mmn6huQDCRyk5eO9u2NbsRKdBYRGndMbwAO1vyNehtW0TUuxddC1vcdXCUctYAMH49H 2020-10-21 15:06:08.630 15896-15911/com.calvin.android.demo2 I/System.out: RIoXg2z+s8KO0BTli2H9Igy69g2ZtwOBhAACgYAsVYqi4LJcuZp8iNKjrPI4jiFxfekwuIx2vmrI 2020-10-21 15:06:08.630 15896-15911/com.calvin.android.demo2 I/System.out: v8yL1602hHirLP85/ibNR8ICGTJK3tkt/FO7nk0DOlLTkct5gXOpzGvp/UuPEONZosxgPHHbf0zQ 2020-10-21 15:06:08.630 15896-15911/com.calvin.android.demo2 I/System.out: NFOWkk6UrOUV4BWcDU6u2OFMf3GAQ4JwUgElTXEI/iyV8m6aD8VCasltcA== 2020-10-21 15:06:08.631 15896-15911/com.calvin.android.demo2 I/System.out: 私钥: MIIBSgIBADCCASsGByqGSM44BAEwggEeAoGBALp0XqBwHX0xv8pzTPn1vYI9xC5eshO2gPWPXOhj 2020-10-21 15:06:08.631 15896-15911/com.calvin.android.demo2 I/System.out: NSWYEl4u3aLJcOWW9zrvb9Zzm6jjH316keUqnhbd1A007N3sXIW43YVjsPcqQLw5g45PTxK83UPs 2020-10-21 15:06:08.631 15896-15911/com.calvin.android.demo2 I/System.out: VGckucwOx38Z1ByI0HW/Hgt8ym3GZ6YRsBNFoJ6AV7ECbHeg9FQ/XvhTAhUAoCMUYSx3rXCqIs7y 2020-10-21 15:06:08.631 15896-15911/com.calvin.android.demo2 I/System.out: kNakJapM0G0CgYBo66ouj4XZz0S3FQaoknrOuSxlYj0UidiXx3NjqEwzSf6gUEVRur+O+xee0pIZ 2020-10-21 15:06:08.631 15896-15911/com.calvin.android.demo2 I/System.out: 7YwfwzGfUqjP+Mmn6huQDCRyk5eO9u2NbsRKdBYRGndMbwAO1vyNehtW0TUuxddC1vcdXCUctYAM 2020-10-21 15:06:08.631 15896-15911/com.calvin.android.demo2 I/System.out: H49HRIoXg2z+s8KO0BTli2H9Igy69g2ZtwQWAhQg4fIBUelmYm8aJvyPOqLadXBAtg== 2020-10-21 15:06:08.636 15896-15911/com.calvin.android.demo2 I/System.out: 签名: 302c0214404e14880800664e6cd8cb1f8d7c9cfb692c789702144c7ecdfe4128001f838042a913ea714eeced0d12 2020-10-21 15:06:08.640 15896-15911/com.calvin.android.demo2 I/System.out: 验签状态: true
最新回复(0)