认证加密签名相关

认证、加密、签名相关命令

一、测试环境证书生成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");
        }
    }
}
posted @ 2023-12-06 14:21  脉动丶  阅读(107)  评论(0)    收藏  举报