接下来我们介绍DSA数字签名,非对称加密的另一种实现。
DSA
DSA-Digital Signature Algorithm 是Schnorr和ElGamal签名算法的变种,被美国NIST作为DSS(DigitalSignature Standard)。简单的说,这是一种更高级的验证方式,用作数字签名。不单单只有公钥、私钥,还有数字签名。私钥加密生成数字签名,公钥验证数据及签名。如果数据和签名不匹配则认为验证失败!数字签名的作用就是校验数据在传输过程中不被修改。数字签名,是单向加密的升级!
通过java代码实现如下: Coder类见Java加密技术(一)
再给出一个测试类:
控制台输出:
注意状态为true,就验证成功!
DSA
DSA-Digital Signature Algorithm 是Schnorr和ElGamal签名算法的变种,被美国NIST作为DSS(DigitalSignature Standard)。简单的说,这是一种更高级的验证方式,用作数字签名。不单单只有公钥、私钥,还有数字签名。私钥加密生成数字签名,公钥验证数据及签名。如果数据和签名不匹配则认为验证失败!数字签名的作用就是校验数据在传输过程中不被修改。数字签名,是单向加密的升级!
通过java代码实现如下: Coder类见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.interfaces.DSAPrivateKey;
- importjava.security.interfaces.DSAPublicKey;
- importjava.security.spec.PKCS8EncodedKeySpec;
- importjava.security.spec.X509EncodedKeySpec;
- importjava.util.HashMap;
- importjava.util.Map;
- /**
- *DSA安全编码组件
- *
- *@author梁栋
- *@version1.0
- *@since1.0
- */
- publicabstractclassDSACoderextendsCoder{
- publicstaticfinalStringALGORITHM="DSA";
- /**
- *默认密钥字节数
- *
- *<pre>
- *DSA
- *DefaultKeysize1024
- *Keysizemustbeamultipleof64,rangingfrom512to1024(inclusive).
- *</pre>
- */
- privatestaticfinalintKEY_SIZE=1024;
- /**
- *默认种子
- */
- privatestaticfinalStringDEFAULT_SEED="0f22507a10bbddd07d8a3082122966e3";
- privatestaticfinalStringPUBLIC_KEY="DSAPublicKey";
- privatestaticfinalStringPRIVATE_KEY="DSAPrivateKey";
- /**
- *用私钥对信息生成数字签名
- *
- *@paramdata
- *加密数据
- *@paramprivateKey
- *私钥
- *
- *@return
- *@throwsException
- */
- publicstaticStringsign(byte[]data,StringprivateKey)throwsException{
- //解密由base64编码的私钥
- byte[]keyBytes=decryptBASE64(privateKey);
- //构造PKCS8EncodedKeySpec对象
- PKCS8EncodedKeySpecpkcs8KeySpec=newPKCS8EncodedKeySpec(keyBytes);
- //KEY_ALGORITHM指定的加密算法
- KeyFactorykeyFactory=KeyFactory.getInstance(ALGORITHM);
- //取私钥匙对象
- PrivateKeypriKey=keyFactory.generatePrivate(pkcs8KeySpec);
- //用私钥对信息生成数字签名
- Signaturesignature=Signature.getInstance(keyFactory.getAlgorithm());
- signature.initSign(priKey);
- signature.update(data);
- returnencryptBASE64(signature.sign());
- }
- /**
- *校验数字签名
- *
- *@paramdata
- *加密数据
- *@parampublicKey
- *公钥
- *@paramsign
- *数字签名
- *
- *@return校验成功返回true失败返回false
- *@throwsException
- *
- */
- publicstaticbooleanverify(byte[]data,StringpublicKey,Stringsign)
- throwsException{
- //解密由base64编码的公钥
- byte[]keyBytes=decryptBASE64(publicKey);
- //构造X509EncodedKeySpec对象
- X509EncodedKeySpeckeySpec=newX509EncodedKeySpec(keyBytes);
- //ALGORITHM指定的加密算法
- KeyFactorykeyFactory=KeyFactory.getInstance(ALGORITHM);
- //取公钥匙对象
- PublicKeypubKey=keyFactory.generatePublic(keySpec);
- Signaturesignature=Signature.getInstance(keyFactory.getAlgorithm());
- signature.initVerify(pubKey);
- signature.update(data);
- //验证签名是否正常
- returnsignature.verify(decryptBASE64(sign));
- }
- /**
- *生成密钥
- *
- *@paramseed
- *种子
- *@return密钥对象
- *@throwsException
- */
- publicstaticMap<String,Object>initKey(Stringseed)throwsException{
- KeyPairGeneratorkeygen=KeyPairGenerator.getInstance(ALGORITHM);
- //初始化随机产生器
- SecureRandomsecureRandom=newSecureRandom();
- secureRandom.setSeed(seed.getBytes());
- keygen.initialize(KEY_SIZE,secureRandom);
- KeyPairkeys=keygen.genKeyPair();
- DSAPublicKeypublicKey=(DSAPublicKey)keys.getPublic();
- DSAPrivateKeyprivateKey=(DSAPrivateKey)keys.getPrivate();
- Map<String,Object>map=newHashMap<String,Object>(2);
- map.put(PUBLIC_KEY,publicKey);
- map.put(PRIVATE_KEY,privateKey);
- returnmap;
- }
- /**
- *默认生成密钥
- *
- *@return密钥对象
- *@throwsException
- */
- publicstaticMap<String,Object>initKey()throwsException{
- returninitKey(DEFAULT_SEED);
- }
- /**
- *取得私钥
- *
- *@paramkeyMap
- *@return
- *@throwsException
- */
- publicstaticStringgetPrivateKey(Map<String,Object>keyMap)
- throwsException{
- Keykey=(Key)keyMap.get(PRIVATE_KEY);
- returnencryptBASE64(key.getEncoded());
- }
- /**
- *取得公钥
- *
- *@paramkeyMap
- *@return
- *@throwsException
- */
- publicstaticStringgetPublicKey(Map<String,Object>keyMap)
- throwsException{
- Keykey=(Key)keyMap.get(PUBLIC_KEY);
- returnencryptBASE64(key.getEncoded());
- }
- }
再给出一个测试类:
- importstaticorg.junit.Assert.*;
- importjava.util.Map;
- importorg.junit.Test;
- /**
- *
- *@author梁栋
- *@version1.0
- *@since1.0
- */
- publicclassDSACoderTest{
- @Test
- publicvoidtest()throwsException{
- StringinputStr="abc";
- byte[]data=inputStr.getBytes();
- //构建密钥
- Map<String,Object>keyMap=DSACoder.initKey();
- //获得密钥
- StringpublicKey=DSACoder.getPublicKey(keyMap);
- StringprivateKey=DSACoder.getPrivateKey(keyMap);
- System.err.println("公钥:\r"+publicKey);
- System.err.println("私钥:\r"+privateKey);
- //产生签名
- Stringsign=DSACoder.sign(data,privateKey);
- System.err.println("签名:\r"+sign);
- //验证签名
- booleanstatus=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
注意状态为true,就验证成功!
本文深入探讨了DSA数字签名的原理与应用,并通过Java代码示例展示了如何生成与验证数字签名,确保数据在传输过程中的完整性和真实性。



445

被折叠的 条评论
为什么被折叠?



