java 验签_Java中使用PSS填充的签名验签工具

本文介绍了一个Java工具类RSASignature,用于实现RSA/PSS签名和验签操作。该类包括了文件摘要计算、RSA私钥解密、签名生成以及签名验证等功能,使用了BouncyCastle库作为安全提供者。
摘要由CSDN通过智能技术生成

引入依赖

org.bouncycastle

bcprov-jdk15on

1.62

签名验签工具类

import java.io.File;

import java.io.FileInputStream;

import java.nio.charset.StandardCharsets;

import java.nio.file.Files;

import java.nio.file.Paths;

import java.security.KeyFactory;

import java.security.MessageDigest;

import java.security.PrivateKey;

import java.security.PublicKey;

import java.security.Security;

import java.security.cert.CertificateFactory;

import java.security.cert.X509Certificate;

import java.security.spec.MGF1ParameterSpec;

import java.security.spec.PKCS8EncodedKeySpec;

import java.security.spec.PSSParameterSpec;

import java.security.spec.X509EncodedKeySpec;

import java.util.Base64;

import javax.crypto.EncryptedPrivateKeyInfo;

import javax.crypto.SecretKeyFactory;

import javax.crypto.spec.PBEKeySpec;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import sun.misc.BASE64Encoder;

/**

* Description

*

*

* @author x00482439

* @version v1.0, 2019-06-10

* @since Security SDK

*/

public class RSASignature {

private static final Logger Logger = LoggerFactory.getLogger(RSASignature.class);

/**

* 签名算法

*/

private static final String SIGN_ALGORITHMS = "SHA256withRSA";

private static final String SIGN_ALGORITHMS_PSS = "SHA256withRSA/PSS";

private static final String ENCODE_ALGORITHM = "SHA-256";

/**

* 生成文件摘要

*

* @param content 文件内容

* @param encode 字符集编码

* @return 文件摘要

*/

public static String digest(String content, String encode) {

try {

MessageDigest messageDigest = MessageDigest.getInstance(ENCODE_ALGORITHM);

messageDigest.update(content.getBytes(encode));

byte[] digestBytes = messageDigest.digest();

return new String(Base64.getEncoder().encode(digestBytes), ICommon.GBK_ENCODEING);

} catch (Exception e) {

Logger.error("Summary calculation failed. {}", e.getMessage());

}

return null;

}

/**

* RSA签名,结果写入签名值文件中

*

* @param file 待签名文件

* @param signFile 签名值文件

* @param signKeyFile 签名私钥文件

* @param keyPassword 签名私钥口令

*/

public static void sign(File file, String signFile, String signKeyFile, String keyPassword) {

try {

// 先解密私钥

String encrypted = new String(Files.readAllBytes(Paths.get(signKeyFile)));

encrypted = encrypted.replace("-----BEGIN ENCRYPTED PRIVATE KEY-----", "");

encrypted = encrypted.replace("-----END ENCRYPTED PRIVATE KEY-----", "");

encrypted = encrypted.replaceAll("\\n", "");

EncryptedPrivateKeyInfo pkInfo = new EncryptedPrivateKeyInfo(Base64.getDecoder().decode(encrypted));

PBEKeySpec keySpec = new PBEKeySpec(keyPassword.toCharArray()); // password

SecretKeyFactory pbeKeyFactory = SecretKeyFactory.getInstance(pkInfo.getAlgName());

PKCS8EncodedKeySpec encodedKeySpec = pkInfo.getKeySpec(pbeKeyFactory.generateSecret(keySpec));

KeyFactory keyFactory = KeyFactory.getInstance("RSA");

PrivateKey priKey = keyFactory.generatePrivate(encodedKeySpec);

// 开始签名

Security.addProvider(new BouncyCastleProvider());

java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS_PSS);

signature.setParameter(new PSSParameterSpec(MGF1ParameterSpec.SHA256.getDigestAlgorithm(), "MGF1",

MGF1ParameterSpec.SHA256, 32, 1));

signature.initSign(priKey);

signature.update(Files.readAllBytes(file.toPath()));

byte[] signed = signature.sign();

String signStr = new String(Base64.getEncoder().encode(signed), StandardCharsets.UTF_8);

System.out.println(signStr);

Files.write(Paths.get(signFile), signStr.getBytes(StandardCharsets.UTF_8));

} catch (Exception e) {

Logger.error("digital signature failed", e);

}

}

/**

* RSA验签名检查

*

* @param originFile 待验证文件

* @param signFile 签名值文件

* @param signCertFile 签名证书文件

* @return 是否验签成功

*/

public static boolean verify(File originFile, String signFile, String signCertFile) {

try {

CertificateFactory fact = CertificateFactory.getInstance("X.509");

X509Certificate certificate = (X509Certificate) fact.generateCertificate(new FileInputStream(signCertFile));

PublicKey pk = certificate.getPublicKey();

byte[] keyBytes = pk.getEncoded();

String publicKey = new BASE64Encoder().encode(keyBytes);

publicKey = publicKey.replaceAll("\\r?\\n", "");

byte[] encodedKey = Base64.getDecoder().decode(publicKey);

KeyFactory keyFactory = KeyFactory.getInstance("RSA");

PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));

Security.addProvider(new BouncyCastleProvider());

java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS_PSS);

signature.setParameter(new PSSParameterSpec(MGF1ParameterSpec.SHA256.getDigestAlgorithm(), "MGF1",

MGF1ParameterSpec.SHA256, 32, 1));

signature.initVerify(pubKey);

signature.update(Files.readAllBytes(originFile.toPath()));

String signStr = new String(Files.readAllBytes(Paths.get(signFile)), StandardCharsets.UTF_8);

return signature.verify(Base64.getDecoder().decode(signStr.replaceAll("\\n", "")));

} catch (Exception e) {

Logger.error("Digital signature verification failed. {}", e.getMessage());

}

return false;

}

}

备注

如果是openssl生成的私钥,则默认为PKCS1,需要转换

PKCS1私钥转换为PKCS8

openssl pkcs8 -topk8 -inform PEM -in sign.key -outform pem -out sign2.key

mv sign2.key sign.key

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值