认证加密签名相关
认证、加密、签名相关命令
一、测试环境证书生成keystore
keytool -importkeystore -srckeystore 8650389_pay-test.anywheelbike.com.jks -destkeystore pay-test.anywheelbike.com.20231018.keystore -deststoretype pkcs12
二、CertBot 生成证书
第一步:安装certbot
yum install certbot -y
第二步:查看certbot版本
certbot --version
第三步:申请证书
certbot -d *.domain.com --manual --preferred-challenges dns-01 --server https://acme-v02.api.letsencrypt.org/directory certonly --agree-tos
第四步:在域名解析中新增TXT记录
Please deploy a DNS TXT record under the name:
_acme-challenge.domain.com.
with the following value:
a8h7Ccrq6UEt7iMLhVszGVvqMl8XU2ipFCXl6ujEGzI
第五步:按回车验证
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/atayun.com-0001/fullchain.pem
Key is saved at: /etc/letsencrypt/live/atayun.com-0001/privkey.pem
This certificate expires on 2024-01-05.
These files will be updated when the certificate renews.
第六步:配置自动续期
三、java读取证书信息到ok http
import com.atayun.nets.click.NETSClickProperties;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import org.springframework.util.ResourceUtils;
import javax.net.ssl.*;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
/**
* @description: CustomOkHttpClientBuilderFactory
*
* @author: dongjie
*/
@Slf4j
public class CustomOkHttpClientBuilderFactory implements OkHttpClientBuilderFactory {
private static final String PROTOCOL = "TLSv1.2";
private static final String KEY_KEYSTORE_TYPE = "PKCS12";
private final NETSClickProperties nETSClickProperties;
public CustomOkHttpClientBuilderFactory(NETSClickProperties nETSClickProperties) {
this.nETSClickProperties = nETSClickProperties;
}
@Override
public OkHttpClient.Builder createBuilder() {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
try (InputStream p12InputStream = ResourceUtils.getURL(nETSClickProperties.getClientStore()).openStream()) {
KeyManager[] keyManagers = getKeyManagers(p12InputStream, nETSClickProperties.getClientStorePassword());
//信任所有服务端证书
TrustManager[] trustManagers = getTrustManagers();
//信任服务端证书
// InputStream cerInputStream = ResourceUtils.getURL(ocbcPayNowProperties.getSeverCert()).openStream();
// TrustManager[] trustManagers = getTrustManagers(cerInputStream, cerInputStream2);
// if (cerInputStream2 != null) {
// cerInputStream2.close();
// }
SSLContext sslContext = getSslContext(keyManagers, trustManagers);
SSLSocketFactory socketFactory = sslContext.getSocketFactory();
builder.sslSocketFactory(socketFactory, (X509TrustManager) trustManagers[0]);
builder.hostnameVerifier(new TrustAllHostnames());
}catch (Exception e){
log.info("nETSClickProperties:{}",nETSClickProperties);
log.error("[NETS]-createBuilder-error:{}",e.getMessage());
}
return builder;
}
private static SSLContext getSslContext(KeyManager[] keyManagers, TrustManager[] trustManagers) throws Exception {
SSLContext sslContext = SSLContext.getInstance(PROTOCOL);
sslContext.init(keyManagers, trustManagers, new SecureRandom());
return sslContext;
}
private static KeyManager[] getKeyManagers(InputStream inputStream, String password) throws Exception {
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
KeyStore keyStore = KeyStore.getInstance(KEY_KEYSTORE_TYPE);
//加载证书
keyStore.load(inputStream, password.toCharArray());
keyManagerFactory.init(keyStore, password.toCharArray());
return keyManagerFactory.getKeyManagers();
}
private static TrustManager[] getTrustManagers() {
TrustManager[] trustAllCerts = buildTrustManagers();
return trustAllCerts;
}
private static TrustManager[] buildTrustManagers() {
return new TrustManager[] {new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) {
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[] {};
}
}};
}
}
四、PGP加解密 字符串
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.bcpg.CompressionAlgorithmTags;
import org.bouncycastle.bcpg.HashAlgorithmTags;
import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags;
import org.bouncycastle.openpgp.PGPCompressedData;
import org.bouncycastle.openpgp.PGPCompressedDataGenerator;
import org.bouncycastle.openpgp.PGPEncryptedData;
import org.bouncycastle.openpgp.PGPEncryptedDataGenerator;
import org.bouncycastle.openpgp.PGPEncryptedDataList;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPLiteralData;
import org.bouncycastle.openpgp.PGPLiteralDataGenerator;
import org.bouncycastle.openpgp.PGPObjectFactory;
import org.bouncycastle.openpgp.PGPOnePassSignature;
import org.bouncycastle.openpgp.PGPOnePassSignatureList;
import org.bouncycastle.openpgp.PGPPrivateKey;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPSignatureGenerator;
import org.bouncycastle.openpgp.PGPSignatureList;
import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator;
import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator;
import org.bouncycastle.openpgp.operator.bc.BcPBESecretKeyDecryptorBuilder;
import org.bouncycastle.openpgp.operator.bc.BcPGPContentSignerBuilder;
import org.bouncycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider;
import org.bouncycastle.openpgp.operator.bc.BcPGPDataEncryptorBuilder;
import org.bouncycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider;
import org.bouncycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory;
import org.bouncycastle.openpgp.operator.bc.BcPublicKeyKeyEncryptionMethodGenerator;
import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
import org.bouncycastle.util.io.Streams;
import org.springframework.util.ResourceUtils;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.SecureRandom;
import java.util.Date;
import java.util.Iterator;
@Slf4j
public class BCPGPUtils {
public PGPPublicKey readPublicKey(String fileName) throws IOException, PGPException {
InputStream keyIn = ResourceUtils.getURL(fileName).openStream();
PGPPublicKey pubKey = readPublicKey(keyIn);
keyIn.close();
return pubKey;
}
public PGPPublicKey readPublicKey(InputStream in) throws IOException, PGPException {
PGPPublicKeyRingCollection pgpPub = new PGPPublicKeyRingCollection(PGPUtil.getDecoderStream(in),
new JcaKeyFingerprintCalculator());
Iterator<PGPPublicKeyRing> keyRingIter = pgpPub.getKeyRings();
while (keyRingIter.hasNext()) {
PGPPublicKeyRing keyRing = keyRingIter.next();
Iterator<PGPPublicKey> keyIter = keyRing.getPublicKeys();
while (keyIter.hasNext()) {
PGPPublicKey key = keyIter.next();
if (key.isEncryptionKey()) {
return key;
}
}
}
throw new IllegalArgumentException("Can't find encryption key in key ring.");
}
public PGPSecretKey readSecretKey(String fileName) throws IOException, PGPException {
InputStream keyIn = ResourceUtils.getURL(fileName).openStream();
PGPSecretKey secKey = readSecretKey(keyIn);
keyIn.close();
return secKey;
}
public PGPSecretKey readSecretKey(InputStream in) throws IOException, PGPException {
PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(in),
new JcaKeyFingerprintCalculator());
Iterator<PGPSecretKeyRing> keyRingIter = pgpSec.getKeyRings();
while (keyRingIter.hasNext()) {
PGPSecretKeyRing keyRing = keyRingIter.next();
Iterator<PGPSecretKey> keyIter = keyRing.getSecretKeys();
while (keyIter.hasNext()) {
PGPSecretKey key = keyIter.next();
if (key.isSigningKey()) {
return key;
}
}
}
throw new IllegalArgumentException("Can't find signing key in key ring.");
}
/**
* Load a secret key ring collection from keyIn and find the private key
* corresponding to keyID if it exists.
*/
public PGPPrivateKey findSecretKey(PGPSecretKeyRingCollection pgpSec, long keyID, char[] pass)
throws PGPException {
PGPSecretKey pgpSecKey = pgpSec.getSecretKey(keyID);
if (pgpSecKey == null) {
return null;
}
return pgpSecKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider("BC").build(pass));
}
public PGPPrivateKey findPrivateKey(InputStream keyIn, long keyID, char[] pass)
throws IOException, PGPException {
PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(keyIn),
new JcaKeyFingerprintCalculator());
return findPrivateKey(pgpSec.getSecretKey(keyID), pass);
}
public PGPPrivateKey findPrivateKey(PGPSecretKey pgpSecKey, char[] pass)
throws PGPException {
if (pgpSecKey == null)
return null;
return pgpSecKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider("BC").build(pass));
}
/**
* 加密
*
* @param message 需加密的payload
* @param publicKeyFile 服务器加密密钥
* @param privateKeyFile 客户端签名密钥
* @param passPhrase 密码(默认为null)
* @return 加密且格式化的密文
*/
public byte[] encryptAndSignMessage(final byte[] message, String publicKeyFile, String privateKeyFile,
char[] passPhrase) throws PGPException {
// getProvider();
try {
log.info("<-----Encrypting the input file using public key-----> {}", publicKeyFile);
final ByteArrayOutputStream out = new ByteArrayOutputStream();
final PGPEncryptedDataGenerator encryptedDataGenerator = new PGPEncryptedDataGenerator(
new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256).setWithIntegrityPacket(true)
.setSecureRandom(new SecureRandom()));
PGPPublicKey pgpPublicKey = readPublicKey(publicKeyFile);
encryptedDataGenerator.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(pgpPublicKey)
.setSecureRandom(new SecureRandom()));
//Armor 默认为true
final OutputStream theOut = new ArmoredOutputStream(out);
final OutputStream encryptedOut = encryptedDataGenerator.open(theOut, new byte[4096]);
final PGPCompressedDataGenerator compressedDataGenerator = new PGPCompressedDataGenerator(
CompressionAlgorithmTags.ZIP);
final OutputStream compressedOut = compressedDataGenerator.open(encryptedOut, new byte[4096]);
log.info("<-----Generating OnePass Signature for signing using private Key-----> {}", privateKeyFile);
PGPSecretKey pgpSec = readSecretKey(privateKeyFile);
PGPPrivateKey signingKey = pgpSec
.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider())
.build(passPhrase));
PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(
pgpPublicKey.getAlgorithm(), HashAlgorithmTags.SHA256));
signatureGenerator.init(PGPSignature.BINARY_DOCUMENT, signingKey);
log.info("<-----Compressing the encrypted data----->");
final Iterator<?> it = pgpSec.getPublicKey().getUserIDs();
if (it.hasNext()) {
final PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
spGen.addSignerUserID(false, (String) it.next());
signatureGenerator.setHashedSubpackets(spGen.generate());
}
log.info("<-----Signing the message after encryption----->");
signatureGenerator.generateOnePassVersion(false).encode(compressedOut);
final PGPLiteralDataGenerator literalDataGenerator = new PGPLiteralDataGenerator();
final OutputStream literalOut = literalDataGenerator.open(compressedOut, PGPLiteralData.BINARY, "filename",
new Date(), new byte[4096]);
final InputStream in = new ByteArrayInputStream(message);
final byte[] buf = new byte[4096];
for (int len; (len = in.read(buf)) > 0; ) {
literalOut.write(buf, 0, len);
signatureGenerator.update(buf, 0, len);
}
in.close();
literalDataGenerator.close();
signatureGenerator.generate().encode(compressedOut);
compressedDataGenerator.close();
encryptedDataGenerator.close();
theOut.close();
log.info("<-----Generated Encrypted and Signed Message successfully----->");
return out.toByteArray();
} catch (Exception ex) {
throw new PGPException("Error in encrypt and sign", ex);
}
}
/**
* 解密
*
* @param encryptedMessage 需解密的密文
* @param publicKeyFile 客户端公钥用于验签
* @param privateKeyFile 服务端私钥用于解密
* @param passPhrase 密码 默认为 null
* @return 解密后的payload
*/
public byte[] decryptedVerifyMessage(byte[] encryptedMessage, String publicKeyFile, String privateKeyFile,
char[] passPhrase) throws IOException, PGPException {
InputStream in = null;
InputStream keyIn = null;
InputStream decryptKeyInput;
try {
in = PGPUtil.getDecoderStream(new ByteArrayInputStream(encryptedMessage));
keyIn = ResourceUtils.getURL(privateKeyFile).openStream();
decryptKeyInput = ResourceUtils.getURL(publicKeyFile).openStream();
PGPObjectFactory pgpF = new PGPObjectFactory(in, new BcKeyFingerprintCalculator());
PGPEncryptedDataList enc;
Object o = pgpF.nextObject();
if (o instanceof PGPEncryptedDataList) {
enc = (PGPEncryptedDataList) o;
} else {
enc = (PGPEncryptedDataList) pgpF.nextObject();
}
Iterator<PGPEncryptedData> it = enc.getEncryptedDataObjects();
PGPPrivateKey sKey = null;
PGPPublicKeyEncryptedData pbe = null;
while (sKey == null && it.hasNext()) {
pbe = (PGPPublicKeyEncryptedData) it.next();
sKey = findPrivateKey(keyIn, pbe.getKeyID(), passPhrase);
}
if (sKey == null) {
close(in);
close(keyIn);
close(decryptKeyInput);
throw new IllegalArgumentException("Secret key for message not found.");
}
log.info("<-----Decrypting the input payload using private key-----> {}", privateKeyFile);
InputStream clear = pbe.getDataStream(new BcPublicKeyDataDecryptorFactory(sKey));
PGPObjectFactory pgpFact = new PGPObjectFactory(clear, new BcKeyFingerprintCalculator());
PGPOnePassSignatureList onePassSignatureList = null;
PGPSignatureList signatureList = null;
Object message = pgpFact.nextObject();
ByteArrayOutputStream actualOutput = new ByteArrayOutputStream();
while (message != null) {
if (message instanceof PGPCompressedData) {
log.info("<-----Decrypting the compressed payload----->");
PGPCompressedData compressedData = (PGPCompressedData) message;
pgpFact = new PGPObjectFactory(compressedData.getDataStream(), new BcKeyFingerprintCalculator());
message = pgpFact.nextObject();
}
if (message instanceof PGPLiteralData) {
Streams.pipeAll(((PGPLiteralData) message).getInputStream(), actualOutput);
} else if (message instanceof PGPOnePassSignatureList) {
onePassSignatureList = (PGPOnePassSignatureList) message;
} else if (message instanceof PGPSignatureList) {
signatureList = (PGPSignatureList) message;
} else {
log.error("<-----Message unknown message type----->");
}
message = pgpFact.nextObject();
}
actualOutput.close();
PGPPublicKey publicKey = null;
byte[] outputBytes = actualOutput.toByteArray();
if (onePassSignatureList == null || signatureList == null) {
throw new PGPException("Poor PGP. Signatures not found.");
} else {
for (int i = 0; i < onePassSignatureList.size(); i++) {
PGPOnePassSignature ops = onePassSignatureList.get(0);
PGPPublicKeyRingCollection pgpRing = new PGPPublicKeyRingCollection(
PGPUtil.getDecoderStream(decryptKeyInput), new BcKeyFingerprintCalculator());
publicKey = pgpRing.getPublicKey(ops.getKeyID());
if (publicKey != null) {
ops.init(new BcPGPContentVerifierBuilderProvider(), publicKey);
ops.update(outputBytes);
PGPSignature signature = signatureList.get(i);
if (ops.verify(signature)) {
log.info("<-----Verifying the one-pass signature using public key-----> {}", publicKeyFile);
Iterator<String> userIds = publicKey.getUserIDs();
while (userIds.hasNext()) {
String userId = userIds.next();
if (null != userId && !userId.isEmpty()) {
log.info("<-----{}----->", userId);
}
}
log.info("<-----Signature verified----->");
} else {
log.error("<-----Signature verification failed----->");
}
}
}
}
if (pbe.isIntegrityProtected() && !pbe.verify()) {
log.error("Data is integrity protected but integrity is lost.");
} else if (publicKey == null) {
log.error("Signature not found");
}
return actualOutput.toByteArray();
} finally {
try {
in.close();
} catch (Exception ex) {
log.error("Exception while closing encrypted message stream...");
}
try {
keyIn.close();
} catch (Exception ex) {
log.error("Exception while closing private key file stream...");
}
}
}
private void close(InputStream in) {
try {
if (null != in) {
in.close();
}
} catch (IOException ex) {
log.error("Exception while closing input stream");
}
}
}
浙公网安备 33010602011771号