Java文件签名与验证

Java文件签名与验证

数字签名与验证只需要用户输入三个参数:

Ø         原文件

Ø         签名信息文件

Ø         用户名

签名过程:

1.         首先从用户名对应的用户注册文件中读取用户信息和私钥,对原文件产生报文摘要,再对摘要进行签名。原文件的报文摘要、对报文摘要的签名都存入签名信息文件。

2.         接收三个输入参数:原文件路径、签名信息文件路径和用户名

3.         从用户注册文件中读取用户信息和私钥

4.         对原文件产生报文摘要、把摘要用对象输出流写入签名信息文件

5.         生成随机源

6.         生成签名对象,用私有密钥随机源初始化签名对象

7.         将原文件的报文摘要输入签名对象

8.         对原文件的报文摘要进行签名,将签名信息用对象输出流写入签名信息文件

验证签名过程:

根据签名过程的逆过程对签名信息对比认证,顺序不能颠倒。

依次从签名信息文件中读取的对象是:原文件的报文摘要,对原文件报文摘要的签名,

1.         接收三个输入参数:原文件路径、签名信息文件路径和用户名

2.         从用户注册文件中读取用户信息和公钥

3.         从签名信息文件中,读取原文摘要和数字签名

4.         产生原文件报文摘要,并与从签名信息文件中读取到的摘要进行对比

5.         生成签名对象,用公有密钥验证签名信息

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是Java代码示例,用于使用SM2证书对数据进行签名验证: /** * SM2证书签名验证示例 */ import java.security.Security; import java.security.KeyFactory; import java.security.PublicKey; import java.security.PrivateKey; import java.security.cert.X509Certificate; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509CertificateStructure; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.digests.SM3Digest; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.signers.SM2Signer; public class SM2CertSignDemo { public static void main(String[] args) { Security.addProvider(new BouncyCastleProvider()); try { // 从证书获取SM2公钥 X509Certificate cert = loadCertificate("test-cert.pem"); PublicKey publicKey = cert.getPublicKey(); byte[] encodedPublicKey = publicKey.getEncoded(); SubjectPublicKeyInfo subjectPublicKeyInfo = SubjectPublicKeyInfo.getInstance(encodedPublicKey); ECPublicKeyParameters ecPublicKeyParameters = new ECPublicKeyParameters(subjectPublicKeyInfo.getPublicKeyData().getBytes(), SM2CurveUtils.SM2_CURVE); // 从密钥文件获取SM2私钥 byte[] privateKeyBytes = loadPrivateKeyBytes("test-key.pem"); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKeyBytes); KeyFactory keyFactory = KeyFactory.getInstance("EC", "BC"); PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec); byte[] encodedPrivateKey = privateKey.getEncoded(); ECPrivateKeyParameters ecPrivateKeyParameters = new ECPrivateKeyParameters(SM2CurveUtils.SM2_CURVE.decodeScalar(encodedPrivateKey), SM2CurveUtils.SM2_CURVE); // 签名示例 byte[] data = "Hello, world!".getBytes("UTF-8"); SM2Signer sm2Signer = new SM2Signer(); sm2Signer.init(true, ecPrivateKeyParameters); sm2Signer.update(data, 0, data.length); byte[] signature = sm2Signer.generateSignature(); System.out.println("Signature: " + bytesToHexString(signature)); // 验证签名示例 sm2Signer.init(false, ecPublicKeyParameters); sm2Signer.update(data, 0, data.length); boolean valid = sm2Signer.verifySignature(signature); System.out.println("Valid: " + valid); } catch (Exception e) { e.printStackTrace(); } } /** * 从证书文件加载X.509证书 */ private static X509Certificate loadCertificate(String certFile) throws Exception { byte[] certBytes = Files.readAllBytes(Paths.get(certFile)); X509CertificateHolder certHolder = new X509CertificateHolder(certBytes); X509CertificateStructure certStructure = certHolder.toASN1Structure(); X509Certificate cert = new JcaX509CertificateConverter().getCertificate(certStructure); return cert; } /** * 从密钥文件加载PKCS#8格式私钥 */ private static byte[] loadPrivateKeyBytes(String keyFile) throws Exception { byte[] keyBytes = Files.readAllBytes(Paths.get(keyFile)); String keyString = new String(keyBytes, "UTF-8"); keyString = keyString.replace("-----BEGIN PRIVATE KEY-----\n", ""); keyString = keyString.replace("-----END PRIVATE KEY-----\n", ""); keyString = keyString.replaceAll("\\s+", ""); return Base64.decode(keyString); } /** * 将字节数组转换为16进制字符串 */ private static String bytesToHexString(byte[] bytes) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < bytes.length; i++) { sb.append(String.format("%02X", bytes[i])); } return sb.toString(); } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值