java dsa算法_JAVA加密算法(DSA)

DSA

DSA-Digital Signature Algorithm 是Schnorr和ElGamal签名算法的变种,被美国NIST作为DSS(DigitalSignature Standard)。简单的说,这是一种更高级的验证方式,用作数字签名。不单单只有公钥、私钥,还有数字签名。私钥加密生成数字签名,公钥验证数据及签名。如果数据和签名不匹配则认为验证失败!也就是说传输中的数据可以不再加密,接收方获得数据后,拿到公钥与签名比对数据是否有效!

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

Java代码

importjava.security.Key;importjava.security.KeyFactory;importjava.security.KeyPair;importjava.security.KeyPairGenerator;importjava.security.PrivateKey;importjava.security.PublicKey;importjava.security.SecureRandom;importjava.security.Signature;importjava.security.spec.PKCS8EncodedKeySpec;importjava.security.spec.X509EncodedKeySpec;importjava.util.HashMap;importjava.util.Map;/*** DSA安全编码组件

**/

public abstract class DSACoder extendsCoder {/*** 可以使用DSA方式获得签名,也可以使用RSA方式获得签名,注意成对儿出现。

*

*

* public static final String KEY_ALGORITHM = "RSA";

* public static final String SIGNATURE_ALGORITHM = "MD5withRSA";

*

**/

public static final String KEY_ALGORITHM = "DSA";public static final String SIGNATURE_ALGORITHM = "DSA";/*** 默认种子*/

private static final String DEFAULT_SEED = "0f22507a10bbddd07d8a3082122966e3";private static final String PUBLIC_KEY = "DSAPublicKey";private static final String PRIVATE_KEY = "DSAPrivateKey";/*** 用私钥对信息生成数字签名

*

*@paramdata

* 加密数据

*@paramprivateKey

* 私钥

*@return*@throwsException*/

public static String sign(byte[] data, String privateKey) throwsException {//解密由base64编码的私钥

byte[] keyBytes =decryptBASE64(privateKey);//构造PKCS8EncodedKeySpec对象

PKCS8EncodedKeySpec pkcs8KeySpec = newPKCS8EncodedKeySpec(keyBytes);//KEY_ALGORITHM 指定的加密算法

KeyFactory keyFactory =KeyFactory.getInstance(KEY_ALGORITHM);//取私钥匙对象

PrivateKey priKey =keyFactory.generatePrivate(pkcs8KeySpec);//用私钥对信息生成数字签名

Signature signature =Signature.getInstance(SIGNATURE_ALGORITHM);

signature.initSign(priKey);

signature.update(data);returnencryptBASE64(signature.sign());

}/*** 校验数字签名

*@paramdata

* 加密数据

*@parampublicKey

* 公钥

*@paramsign

* 数字签名

*

*@return校验成功返回true 失败返回false

*@throwsException

**/

public static boolean verify(byte[] data, String publicKey, String sign)throwsException {//解密由base64编码的公钥

byte[] keyBytes =decryptBASE64(publicKey);//构造X509EncodedKeySpec对象

X509EncodedKeySpec keySpec = newX509EncodedKeySpec(keyBytes);//KEY_ALGORITHM 指定的加密算法

KeyFactory keyFactory =KeyFactory.getInstance(KEY_ALGORITHM);//取公钥匙对象

PublicKey pubKey =keyFactory.generatePublic(keySpec);

Signature signature=Signature.getInstance(SIGNATURE_ALGORITHM);

signature.initVerify(pubKey);

signature.update(data);//验证签名是否正常

returnsignature.verify(decryptBASE64(sign));

}/*** 生成密钥

*

*@paramseed

* 种子

*@return密钥对象

*@throwsException*/

public static Map initKey(String seed) throwsException {

KeyPairGenerator keygen=KeyPairGenerator.getInstance(KEY_ALGORITHM);//初始化随机产生器

SecureRandom secureRandom = newSecureRandom();

secureRandom.setSeed(seed.getBytes());

keygen.initialize(1024, secureRandom);

KeyPair keys=keygen.genKeyPair();

PublicKey publicKey=keys.getPublic();

PrivateKey privateKey=keys.getPrivate();

Map map = new HashMap(2);

map.put(PUBLIC_KEY, publicKey);

map.put(PRIVATE_KEY, privateKey);returnmap;

}/*** 默认生成密钥

*

*@return密钥对象

*@throwsException*/

public static Map initKey() throwsException {returninitKey(DEFAULT_SEED);

}/*** 取得私钥

*

*@paramkeyMap

*@return*@throwsException*/

public static String getPrivateKey(MapkeyMap)throwsException {

Key key=(Key) keyMap.get(PRIVATE_KEY);returnencryptBASE64(key.getEncoded());

}/*** 取得公钥

*

*@paramkeyMap

*@return*@throwsException*/

public static String getPublicKey(MapkeyMap)throwsException {

Key key=(Key) keyMap.get(PUBLIC_KEY);returnencryptBASE64(key.getEncoded());

}

}importjava.security.Key;importjava.security.KeyFactory;importjava.security.KeyPair;importjava.security.KeyPairGenerator;importjava.security.PrivateKey;importjava.security.PublicKey;importjava.security.SecureRandom;importjava.security.Signature;importjava.security.spec.PKCS8EncodedKeySpec;importjava.security.spec.X509EncodedKeySpec;importjava.util.HashMap;importjava.util.Map;/*** DSA安全编码组件

**/

public abstract class DSACoder extendsCoder {/*** 可以使用DSA方式获得签名,也可以使用RSA方式获得签名,注意成对儿出现。

*

*

* public static final String KEY_ALGORITHM = "RSA";

* public static final String SIGNATURE_ALGORITHM = "MD5withRSA";

*

**/

public static final String KEY_ALGORITHM = "DSA";public static final String SIGNATURE_ALGORITHM = "DSA";/*** 默认种子*/

private static final String DEFAULT_SEED = "0f22507a10bbddd07d8a3082122966e3";private static final String PUBLIC_KEY = "DSAPublicKey";private static final String PRIVATE_KEY = "DSAPrivateKey";/*** 用私钥对信息生成数字签名

*

*@paramdata

* 加密数据

*@paramprivateKey

* 私钥

*@return*@throwsException*/

public static String sign(byte[] data, String privateKey) throwsException {//解密由base64编码的私钥

byte[] keyBytes =decryptBASE64(privateKey);//构造PKCS8EncodedKeySpec对象

PKCS8EncodedKeySpec pkcs8KeySpec = newPKCS8EncodedKeySpec(keyBytes);//KEY_ALGORITHM 指定的加密算法

KeyFactory keyFactory =KeyFactory.getInstance(KEY_ALGORITHM);//取私钥匙对象

PrivateKey priKey =keyFactory.generatePrivate(pkcs8KeySpec);//用私钥对信息生成数字签名

Signature signature =Signature.getInstance(SIGNATURE_ALGORITHM);

signature.initSign(priKey);

signature.update(data);returnencryptBASE64(signature.sign());

}/*** 校验数字签名

*@paramdata

* 加密数据

*@parampublicKey

* 公钥

*@paramsign

* 数字签名

*

*@return校验成功返回true 失败返回false

*@throwsException

**/

public static boolean verify(byte[] data, String publicKey, String sign)throwsException {//解密由base64编码的公钥

byte[] keyBytes =decryptBASE64(publicKey);//构造X509EncodedKeySpec对象

X509EncodedKeySpec keySpec = newX509EncodedKeySpec(keyBytes);//KEY_ALGORITHM 指定的加密算法

KeyFactory keyFactory =KeyFactory.getInstance(KEY_ALGORITHM);//取公钥匙对象

PublicKey pubKey =keyFactory.generatePublic(keySpec);

Signature signature=Signature.getInstance(SIGNATURE_ALGORITHM);

signature.initVerify(pubKey);

signature.update(data);//验证签名是否正常

returnsignature.verify(decryptBASE64(sign));

}/*** 生成密钥

*

*@paramseed

* 种子

*@return密钥对象

*@throwsException*/

public static Map initKey(String seed) throwsException {

KeyPairGenerator keygen=KeyPairGenerator.getInstance(KEY_ALGORITHM);//初始化随机产生器

SecureRandom secureRandom = newSecureRandom();

secureRandom.setSeed(seed.getBytes());

keygen.initialize(1024, secureRandom);

KeyPair keys=keygen.genKeyPair();

PublicKey publicKey=keys.getPublic();

PrivateKey privateKey=keys.getPrivate();

Map map = new HashMap(2);

map.put(PUBLIC_KEY, publicKey);

map.put(PRIVATE_KEY, privateKey);returnmap;

}/*** 默认生成密钥

*

*@return密钥对象

*@throwsException*/

public static Map initKey() throwsException {returninitKey(DEFAULT_SEED);

}/*** 取得私钥

*

*@paramkeyMap

*@return*@throwsException*/

public static String getPrivateKey(MapkeyMap)throwsException {

Key key=(Key) keyMap.get(PRIVATE_KEY);returnencryptBASE64(key.getEncoded());

}/*** 取得公钥

*

*@paramkeyMap

*@return*@throwsException*/

public static String getPublicKey(MapkeyMap)throwsException {

Key key=(Key) keyMap.get(PUBLIC_KEY);returnencryptBASE64(key.getEncoded());

}

}

不仅可以使用DSA算法,同样也可以使用RSA算法做数字签名,但要注意成对出现:public static final String KEY_ALGORITHM = "RSA";public static final String SIGNATURE_ALGORITHM = "MD5withRSA";

再给出一个测试类:

Java代码import static org.junit.Assert.*;importjava.util.Map;importorg.junit.Test;/****/

public classDSACoderTest {

@Testpublic void test() throwsException {

String inputStr= "abc";byte[] data =inputStr.getBytes();//构建密钥

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

}

}import static org.junit.Assert.*;importjava.util.Map;importorg.junit.Test;/****/

public classDSACoderTest {

@Testpublic void test() throwsException {

String inputStr= "abc";byte[] data =inputStr.getBytes();//构建密钥

Map 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

公钥:

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值