非对称加密 DSA算法
生活随笔
收集整理的這篇文章主要介紹了
非对称加密 DSA算法
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
原理
數(shù)字簽名算法(DSA - Digital Signature Algorithm)是用于數(shù)字簽名的算法,基于模算數(shù)和離散對(duì)數(shù)的復(fù)雜度。DSA是Schnorr和ElGamal簽名方案的變體。
DSA 算法包含了四種操作:密鑰生成、密鑰分發(fā)、簽名、驗(yàn)證
密鑰生成包含兩個(gè)階段。第一階段是算法參數(shù)的選擇,可以在系統(tǒng)的不同用戶之間共享,而第二階段則為每個(gè)用戶計(jì)算獨(dú)立的密鑰組合。
簽名者需要透過可信任的管道發(fā)布公鑰 y,并且安全地保護(hù) x 不被其他人知道。
下列密碼學(xué)庫(kù)有提供 DSA 的支持:
- OpenSSL
- GnuTLS
- wolfCrypt
- Crypto++
- cryptlib
- Botan
- Bouncy Castle
- libgcrypt
- Nettle
數(shù)據(jù)來(lái)源 – 維基百科
Java jdk實(shí)現(xiàn)
DsaUtils.java
package crypto.dsa;import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor;import java.security.*; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec;/*** 非對(duì)稱加密 DSA 不能用于加密數(shù)據(jù),只能用于數(shù)字簽名*/ public class DsaUtils {private static final String ALGORITHM = "DSA";/*** @link {https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Signature}*/private static final String DEFAULT_SIGNATURE_ALGORITHM = "SHA1withDSA";/*** This must be a multiple of 64, ranging from 512 to 1024 (inclusive), or 2048. The default keysize is 1024.*/private static final int DEFAULT_KEY_SIZE = 1024;/*** 生成密鑰對(duì)** @link {https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#KeyPairGenerator}*/public static InnerKey generateKey() throws NoSuchAlgorithmException {return generateKey(DEFAULT_KEY_SIZE);}/*** 生成密鑰對(duì)** @param keysize* @return* @throws NoSuchAlgorithmException*/public static InnerKey generateKey(int keysize) throws NoSuchAlgorithmException {// 初始化密鑰KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);keyPairGenerator.initialize(keysize);KeyPair keyPair = keyPairGenerator.generateKeyPair();//DSAPublicKey dsaPublicKey = (DSAPublicKey) keyPair.getPublic();//DSAPrivateKey dsaPrivateKey = (DSAPrivateKey) keyPair.getPrivate();return InnerKey.builder().publicKey(keyPair.getPublic().getEncoded()).privateKey(keyPair.getPrivate().getEncoded()).build();}public static byte[] sign(byte[] privateKey, byte[] data)throws InvalidKeySpecException, NoSuchAlgorithmException, InvalidKeyException, SignatureException {return sign(privateKey, data, DEFAULT_SIGNATURE_ALGORITHM);}/*** 使用私鑰進(jìn)行簽名** @param privateKey 私鑰* @param data 數(shù)據(jù)* @param signatureAlgorithm 簽名算法* @return* @throws Exception*/public static byte[] sign(byte[] privateKey, byte[] data, String signatureAlgorithm)throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException {KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKey);PrivateKey privateKey2 = keyFactory.generatePrivate(pkcs8EncodedKeySpec);Signature signature = Signature.getInstance(signatureAlgorithm);signature.initSign(privateKey2);signature.update(data);byte[] bytes = signature.sign();return bytes;}public static boolean verifySign(byte[] publicKey, byte[] data, byte[] sign)throws InvalidKeySpecException, NoSuchAlgorithmException, InvalidKeyException, SignatureException {return verifySign(publicKey, data, sign, DEFAULT_SIGNATURE_ALGORITHM);}/*** 使用公鑰驗(yàn)證簽名** @param publicKey 公鑰* @param data 數(shù)據(jù)* @param sign 數(shù)據(jù)簽名* @param signatureAlgorithm 簽名算法* @return* @throws Exception*/public static boolean verifySign(byte[] publicKey, byte[] data, byte[] sign, String signatureAlgorithm)throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException {KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKey);PublicKey publicKey2 = keyFactory.generatePublic(x509EncodedKeySpec);Signature signature = Signature.getInstance(signatureAlgorithm);signature.initVerify(publicKey2);signature.update(data);boolean bool = signature.verify(sign);return bool;}@Data@NoArgsConstructor@AllArgsConstructor@Builderpublic static class InnerKey {private byte[] publicKey;private byte[] privateKey;} }測(cè)試代碼
package crypto.dsa;import org.apache.commons.codec.binary.Base64;public class DsaUtilsTest {public static void main(String[] args) throws Exception {String text = "你好世界 DSA簽名";DsaUtils.InnerKey innerKey = DsaUtils.generateKey();System.out.println("公鑰:" + Base64.encodeBase64String(innerKey.getPublicKey()));System.out.println("私鑰:" + Base64.encodeBase64String(innerKey.getPrivateKey()));byte[] sign = DsaUtils.sign(innerKey.getPrivateKey(), text.getBytes());System.out.println("原文:" + text);System.out.println("數(shù)字簽名:" + Base64.encodeBase64String(sign));boolean bool = DsaUtils.verifySign(innerKey.getPublicKey(), text.getBytes(), sign);System.out.println("驗(yàn)簽結(jié)果:" + bool);} }Java jdk實(shí)現(xiàn) ECDSA
package crypto.dsa;import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor;import java.security.*; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec;public class EcDsaUtils {private static final String ALGORITHM = "EC";/*** NONEwithECDSA* SHA1withECDSA* SHA224withECDSA* SHA256withECDSA* SHA384withECDSA* SHA512withECDSA** @link {https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Signature}*/public static final String DEFAULT_SIGNATURE_ALGORITHM = "SHA1withECDSA";public enum SignatureAlgorithm {NONEwithECDSA,SHA1withECDSA,SHA224withECDSA,SHA256withECDSA,SHA384withECDSA,SHA512withECDSA}public static InnerKey generateKey() throws Exception {return generateKey(256);}/*** 初始化密鑰** @param keySize Keysize must range from 112 to 571 (inclusive).* @return* @throws Exception* @link {https://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html#SunEC}*/public static InnerKey generateKey(int keySize) throws Exception {KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);keyPairGenerator.initialize(keySize);KeyPair keyPair = keyPairGenerator.generateKeyPair();//ECPublicKey ecPublicKey = (ECPublicKey) keyPair.getPublic();//ECPrivateKey ecPrivateKey = (ECPrivateKey) keyPair.getPrivate();return InnerKey.builder().publicKey(keyPair.getPublic().getEncoded()).privateKey(keyPair.getPrivate().getEncoded()).build();}public static byte[] sign(byte[] privateKey, byte[] data) throws Exception {return sign(privateKey, data, DEFAULT_SIGNATURE_ALGORITHM);}/*** 執(zhí)行簽名** @param privateKey 私鑰* @param data 數(shù)據(jù)* @param algorithm 簽名算法 {@link SignatureAlgorithm}* @return* @throws Exception*/public static byte[] sign(byte[] privateKey, byte[] data, String algorithm) throws Exception {KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKey);PrivateKey privateKey2 = keyFactory.generatePrivate(pkcs8EncodedKeySpec);Signature signature = Signature.getInstance(algorithm);signature.initSign(privateKey2);signature.update(data);return signature.sign();}public static boolean verifySign(byte[] publicKey, byte[] data, byte[] sign) throws Exception {return verifySign(publicKey, data, sign, DEFAULT_SIGNATURE_ALGORITHM);}/*** 驗(yàn)證簽名** @param publicKey 公鑰* @param data 數(shù)據(jù)* @param sign 數(shù)據(jù)簽名* @param algorithm 簽名算法 {@link SignatureAlgorithm}* @return* @throws Exception*/public static boolean verifySign(byte[] publicKey, byte[] data, byte[] sign, String algorithm) throws Exception {KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKey);PublicKey publicKey2 = keyFactory.generatePublic(x509EncodedKeySpec);Signature signature = Signature.getInstance(algorithm);signature.initVerify(publicKey2);signature.update(data);return signature.verify(sign);}@Data@NoArgsConstructor@AllArgsConstructor@Builderpublic static class InnerKey {private byte[] publicKey;private byte[] privateKey;} } package crypto.dsa;import org.apache.commons.codec.binary.Base64;public class EcDsaUtilsTest {public static void main(String[] args) throws Exception {String text = "你好世界 ECDSA簽名";EcDsaUtils.InnerKey innerKey = EcDsaUtils.generateKey(112);System.out.println("公鑰:" + Base64.encodeBase64String(innerKey.getPublicKey()));System.out.println("私鑰:" + Base64.encodeBase64String(innerKey.getPrivateKey()));byte[] sign = EcDsaUtils.sign(innerKey.getPrivateKey(), text.getBytes(),EcDsaUtils.SignatureAlgorithm.SHA224withECDSA.name());System.out.println("原文:" + text);System.out.println("數(shù)字簽名:" + Base64.encodeBase64String(sign));boolean bool = EcDsaUtils.verifySign(innerKey.getPublicKey(), text.getBytes(), sign,EcDsaUtils.SignatureAlgorithm.SHA224withECDSA.name());System.out.println(bool);} }code
總結(jié)
以上是生活随笔為你收集整理的非对称加密 DSA算法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: TIM系列激光雷达
- 下一篇: SLAM中边缘化与一致性