您的位置:首页 > 编程语言 > Java开发

Java加密技术(六)——数字签名算法DSA

2015-03-17 09:53 417 查看
转载自http://snowolf.iteye.com/blog/382749

接下来我们介绍DSA数字签名,非对称加密的另一种实现。

DSA

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






通过java代码实现如下:Coder类见 Java加密技术(一)

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());

}

}

再给出一个测试类:

Java代码


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);

}

}

控制台输出:

Console代码


公钥:

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

注意状态为true,就验证成功!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: