java中的接口是类吗
261
2022-10-12
Java加解密之数字签名算法(数字签名基础结构加密算法)
1. 简介
数字签名(英语:Digital Signature,又称公钥数字签名)是一种功能类似写在纸上的普通签名、但是使用了公钥加密领域的技术,以用于鉴别数字信息的方法。一套数字签名通常会定义两种互补的运算,一个用于签名,另一个用于验证。法律用语中的电子签章与数字签名代表之意义并不相同。电子签章指的是依附于电子文件并与其相关联,用以辨识及确认电子文件签署人身份、资格及电子文件真伪者;数字签名则是以数学算法或其他方式运算对其加密而形成的电子签章。意即并非所有的电子签章都是数字签名。
数字前面的简单原理如下:
通常会使用公钥加密,用私钥解密。而在数字签名中,会使用私钥加密(相当于生成签名),公钥解密(相当于验证签名)。
可以直接对消息进行签名(即使用私钥加密,此时加密的目的是为了签名,而不是保密),验证者用公钥正确解密消息,如果和原消息一致,则验证签名成功。但通常会对消息的散列值签名,因为通常散列值的长度远小于消息原文,使得签名(非对称加密)的效率大大提高。注意,计算消息的散列值不是数字签名的必要步骤。
在实际使用中,我们既想加密消息,又想签名,所以要对加密和签名组合使用,比如TLS就组合了加密和签名。
数字签名应用了公钥密码领域使用的单向函数原理。单向函数指的是正向操作非常简单,而逆向操作非常困难的函数,比如大整数乘法。这种函数往往提供一种难解或怀疑难解的数学问题。目前,公钥密码领域具备实用性的三个怀疑难解问题为:质数分解,离散对数和椭圆曲线问题。
注:数字签名是为了验证数据完整性、认证数据来源、抗否认等。
2. 数字签名算法--RSA
RSA也可以用来为一个消息署名。
RSA代码实现:
package com.bity.digitalsignature;import org.apache.commons.codec.binary.Hex;import java.security.KeyFactory;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.PrivateKey;import java.security.PublicKey;import java.security.Signature;import java.security.interfaces.RSAPrivateKey;import java.security.interfaces.RSAPublicKey;import java.security.spec.PKCS8EncodedKeySpec;import java.security.spec.X509EncodedKeySpec;/** *
Title: DsRsa
*Description: RSA数字前面
*Company: > *
Project: security
* * @author WEIQI * @version 1.0 * @date 2022/4/28 14:21 */public class DsRsa { private static final String src = "I'm RSA digital signature security info"; public static void main(String[] args) { jdkRsa(); } /** * JDK-RSA数字签名 * * @author: WEIQI * @date: 2022/4/28 14:23 */ private static void jdkRsa() { try { //1.初始化密钥 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); keyPairGenerator.initialize(512); KeyPair keyPair = keyPairGenerator.generateKeyPair(); RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic(); RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate(); //2.执行签名 PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded()); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); Signature signature = Signature.getInstance("MD5withRSA"); signature.initSign(privateKey); signature.update(src.getBytes()); byte[] result = signature.sign(); System.out.println("jdk rsa sign : " + Hex.encodeHexString(result)); //3.验证签名 X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded()); keyFactory = KeyFactory.getInstance("RSA"); PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec); signature = Signature.getInstance("MD5withRSA"); signature.initVerify(publicKey); signature.update(src.getBytes()); boolean bool = signature.verify(result); System.out.println("jdk rsa verify : " + bool); } catch (Exception e) { e.printStackTrace(); } }}运行结果:
jdk rsa sign : 7a48c41e5a5d0d2afe60fd05d1219af78f4907ac79eeb0db50ea3ad5646a9b2f8303109b5f040f59e85d3f08cc25c34a6c3f03f5d23fb1c9f04c4dc5ceaf3b9cjdk rsa verify : true
RSA数字签名图示:
3. 数字签名算法--DSA
数字签名算法(DSA)是用于数字签名的联邦信息处理标准之一,基于模算数和离散对数的复杂度。DSA是Schnorr和ElGamal签名方案的变体。
DSA代码实现:
package com.bity.digitalsignature;import org.apache.commons.codec.binary.Hex;import java.security.KeyFactory;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.PrivateKey;import java.security.PublicKey;import java.security.Signature;import java.security.interfaces.DSAPrivateKey;import java.security.interfaces.DSAPublicKey;import java.security.spec.PKCS8EncodedKeySpec;import java.security.spec.X509EncodedKeySpec;/** *
Title: DsDsa
*Description: DSA算法实现
*Company: > *
Project: security
* * @author WEIQI * @version 1.0 * @date 2022/4/28 14:34 */public class DsDsa { private static final String src = "I'm DSA digital signature security info"; public static void main(String[] args) { jdkDsa(); } /** * JDK-DSA数字签名实现 * * @author: WEIQI * @date: 2022/4/28 14:36 */ private static void jdkDsa() { try { //1.初始化密钥 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DSA"); keyPairGenerator.initialize(512); KeyPair keyPair = keyPairGenerator.generateKeyPair(); DSAPublicKey dsaPublicKey = (DSAPublicKey) keyPair.getPublic(); DSAPrivateKey dsaPrivateKey = (DSAPrivateKey)keyPair.getPrivate(); //2.执行签名 PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(dsaPrivateKey.getEncoded()); KeyFactory keyFactory = KeyFactory.getInstance("DSA"); PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); Signature signature = Signature.getInstance("SHA1withDSA"); signature.initSign(privateKey); signature.update(src.getBytes()); byte[] result = signature.sign(); System.out.println("jdk dsa sign : " + Hex.encodeHexString(result)); //3.验证签名 X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(dsaPublicKey.getEncoded()); keyFactory = KeyFactory.getInstance("DSA"); PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec); signature = Signature.getInstance("SHA1withDSA"); signature.initVerify(publicKey); signature.update(src.getBytes()); boolean bool = signature.verify(result); System.out.println("jdk dsa verify : " + bool); } catch (Exception e) { e.printStackTrace(); } } }运行结果:
jdk dsa sign : 302c02140e84921c75543572355259ecd19a099c1a9632ab0214452ba60580452aa21e0996ee358e287eb41207d4jdk dsa verify : true
DSA数字签名图示:
4. 数字签名算法--ECDSA
椭圆曲线数字签名算法(英语:Elliptic Curve Digital Signature Algorithm,缩写作 ECDSA)是一种基于椭圆曲线密码学的公开金钥加密算法。1985年,Koblitz和Miller把数字签名算法移植到椭圆曲线上,椭圆曲线数字签名算法由此诞生。
ECDSA代码实现:
package com.bity.digitalsignature;import org.apache.commons.codec.binary.Hex;import java.security.KeyFactory;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.PrivateKey;import java.security.PublicKey;import java.security.Signature;import java.security.interfaces.ECPrivateKey;import java.security.interfaces.ECPublicKey;import java.security.spec.PKCS8EncodedKeySpec;import java.security.spec.X509EncodedKeySpec;/** *
Title: DsEcdsa
*Description: ECDSA数字签名实现
*Company: > *
Project: security
* * @author WEIQI * @version 1.0 * @date 2022/4/28 14:41 */public class DsEcdsa { private static final String src = "I'm ECDSA digital signature security info"; public static void main(String[] args) { jdkEcdsa(); } /** * JDK-ECDSA数字签名实现 * * @author: WEIQI * @date: 2022/4/28 14:42 */ private static void jdkEcdsa() { try { //1.初始化密钥 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC"); keyPairGenerator.initialize(256); KeyPair keyPair = keyPairGenerator.generateKeyPair(); ECPublicKey ecPublicKey = (ECPublicKey)keyPair.getPublic(); ECPrivateKey ecPrivateKey = (ECPrivateKey)keyPair.getPrivate(); //2.执行签名 PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(ecPrivateKey.getEncoded()); KeyFactory keyFactory = KeyFactory.getInstance("EC"); PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); Signature signature = Signature.getInstance("SHA1withECDSA"); signature.initSign(privateKey); signature.update(src.getBytes()); byte[] result = signature.sign(); System.out.println("jdk ecdsa sign : " + Hex.encodeHexString(result)); //3.验证签名 X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(ecPublicKey.getEncoded()); keyFactory = KeyFactory.getInstance("EC"); PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec); signature = Signature.getInstance("SHA1withECDSA"); signature.initVerify(publicKey); signature.update(src.getBytes()); boolean bool = signature.verify(result); System.out.println("jdk ecdsa verify : " + bool); } catch (Exception e) { e.printStackTrace(); } }}运行结果:
jdk ecdsa sign : 3046022100aeac2ff850c5ccb67d50fc65a3775951f6c73ab6708e0f0519214c71290abac9022100f48828aeff296b7f1aa1dd0d425284cfb11bc3cf148fa4112a8f50d32aa18a74jdk ecdsa verify : true
ECDSA数字签名图示:
我们日常使用的微软的产品(比如操作系统密钥)就是使用ECDSA实现的。
5. 总结
以上就是数字签名算法的所有内容,实际业务有涉及到数字签名的场景,可以根据具体场景选择相应的算法实现。
附加
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~