package crypto

import ( 'crypto' 'crypto/rand' 'crypto/rsa' 'crypto/x509' 'encoding/base64' 'encoding/pem' 'errors' 'github.com/containous/traefik/v2/pkg/log' )

// pkcsClient 定义了PKCS格式的RSA客户端 type pkcsClient struct { privateKey *rsa.PrivateKey publicKey *rsa.PublicKey }

// Type 定义了私钥类型 type Type int64

const ( PKCS1 Type = iota PKCS8 )

// Encrypt 使用公钥加密明文 func (this *pkcsClient) Encrypt(plaintext []byte) ([]byte, error) { return rsa.EncryptPKCS1v15(rand.Reader, this.publicKey, plaintext) }

// Decrypt 使用私钥解密密文 func (this *pkcsClient) Decrypt(ciphertext []byte) ([]byte, error) { return rsa.DecryptPKCS1v15(rand.Reader, this.privateKey, ciphertext) }

// Sign 使用私钥对数据签名 func (this *pkcsClient) Sign(src []byte, hash crypto.Hash) ([]byte, error) { h := hash.New() h.Write(src) hashed := h.Sum(nil) return rsa.SignPKCS1v15(rand.Reader, this.privateKey, hash, hashed) }

// Verify 使用公钥验证签名 func (this *pkcsClient) Verify(src []byte, sign []byte, hash crypto.Hash) error { h := hash.New() h.Write(src) hashed := h.Sum(nil) return rsa.VerifyPKCS1v15(this.publicKey, hash, hashed, sign) }

// Cipher 定义了加密解密和签名验证接口 type Cipher interface { Encrypt(plaintext []byte) ([]byte, error) Decrypt(ciphertext []byte) ([]byte, error) Sign(src []byte, hash crypto.Hash) ([]byte, error) Verify(src []byte, sign []byte, hash crypto.Hash) error }

// NewDefault 创建默认的RSA客户端,使用PKCS8私钥格式,pem编码 func NewDefault(privateKey, publicKey string) (Cipher, error) { blockPri, _ := pem.Decode([]byte(privateKey)) if blockPri == nil { return nil, errors.New('private key error') }

blockPub, _ := pem.Decode([]byte(publicKey))
if blockPub == nil {
	return nil, errors.New('public key error')
}

return NewRsa(blockPri.Bytes, blockPub.Bytes, PKCS8)

}

// NewRsa 创建RSA客户端 func NewRsa(privateKey, publicKey []byte, privateKeyType Type) (Cipher, error) { priKey, err := genPriKey(privateKey, privateKeyType) if err != nil { return nil, err } pubKey, err := genPubKey(publicKey) if err != nil { return nil, err } return &pkcsClient{privateKey: priKey, publicKey: pubKey}, nil }

// genPubKey 解析公钥 func genPubKey(publicKey []byte) (*rsa.PublicKey, error) { pub, err := x509.ParsePKIXPublicKey(publicKey) if err != nil { return nil, err } return pub.(*rsa.PublicKey), nil }

// genPriKey 解析私钥 func genPriKey(privateKey []byte, privateKeyType Type) (*rsa.PrivateKey, error) { var priKey *rsa.PrivateKey var err error switch privateKeyType { case PKCS1: { priKey, err = x509.ParsePKCS1PrivateKey([]byte(privateKey)) if err != nil { return nil, err } } case PKCS8: { prkI, err := x509.ParsePKCS8PrivateKey([]byte(privateKey)) if err != nil { return nil, err } priKey = prkI.(*rsa.PrivateKey) } default: { return nil, errors.New('unsupport private key type') } } return priKey, nil }

// KeyPair 生成密钥对,以base64编码字符串形式返回 func KeyPair() (priKey, pubKey string, err error) { privateKey, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { log.WithoutContext().Errorln(err) return } priKey = base64.StdEncoding.EncodeToString(x509.MarshalPKCS1PrivateKey(privateKey))

// 生成公钥文件
publicKey := &privateKey.PublicKey
derPkix, err := x509.MarshalPKIXPublicKey(publicKey)
if err != nil {
	log.WithoutContext().Errorln(err)
	return
}
pubKey = base64.StdEncoding.EncodeToString(derPkix)
return

}

// KeyPairPem 生成密钥对,以pem编码字符串形式返回 func KeyPairPem() (priKey, pubKey string, err error) { privateKey, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { return '', '', err } var pemPrivateBlock = &pem.Block{ Type: 'RSA PRIVATE KEY', Bytes: x509.MarshalPKCS1PrivateKey(privateKey), } priKey = string(pem.EncodeToMemory(pemPrivateBlock))

// 生成公钥文件
publicKey := &privateKey.PublicKey
derPkix, err := x509.MarshalPKIXPublicKey(publicKey)
if err != nil {
	return '', '', err
}
block := &pem.Block{
	Type:  'RSA PUBLIC KEY',
	Bytes: derPkix,
}
pubKey = string(pem.EncodeToMemory(block))
return priKey, pubKey, nil

}

// Java版本实现 package crypto;

import java.nio.charset.StandardCharsets; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import javax.crypto.Cipher;

public class CipherUtils {

private static final String RSA_ALGORITHM = 'RSA';

// 加密
public static byte[] encrypt(byte[] plaintext, byte[] publicKeyBytes) throws Exception {
	PublicKey publicKey = KeyFactory.getInstance(RSA_ALGORITHM).generatePublic(new X509EncodedKeySpec(publicKeyBytes));
	Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
	cipher.init(Cipher.ENCRYPT_MODE, publicKey);
	return cipher.doFinal(plaintext);
}

// 解密
public static byte[] decrypt(byte[] ciphertext, byte[] privateKeyBytes) throws Exception {
	PrivateKey privateKey = KeyFactory.getInstance(RSA_ALGORITHM).generatePrivate(new PKCS8EncodedKeySpec(privateKeyBytes));
	Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
	cipher.init(Cipher.DECRYPT_MODE, privateKey);
	return cipher.doFinal(ciphertext);
}

// 签名
public static byte[] sign(byte[] message, byte[] privateKeyBytes) throws Exception {
	PrivateKey privateKey = KeyFactory.getInstance(RSA_ALGORITHM).generatePrivate(new PKCS8EncodedKeySpec(privateKeyBytes));
	Signature signature = Signature.getInstance('SHA256withRSA');
	signature.initSign(privateKey);
	signature.update(message);
	return signature.sign();
}

// 验证签名
public static boolean verify(byte[] message, byte[] signatureBytes, byte[] publicKeyBytes) throws Exception {
	PublicKey publicKey = KeyFactory.getInstance(RSA_ALGORITHM).generatePublic(new X509EncodedKeySpec(publicKeyBytes));
	Signature signature = Signature.getInstance('SHA256withRSA');
	signature.initVerify(publicKey);
	signature.update(message);
	return signature.verify(signatureBytes);
}

public static void main(String[] args) throws Exception {
	// 加密和解密
	String plaintext = 'Hello, World!';
	String publicKeyBase64 = 'YOUR_PUBLIC_KEY';
	String privateKeyBase64 = 'YOUR_PRIVATE_KEY';

	byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyBase64);
	byte[] privateKeyBytes = Base64.getDecoder().decode(privateKeyBase64);

	byte[] ciphertext = encrypt(plaintext.getBytes(StandardCharsets.UTF_8), publicKeyBytes);
	byte[] decryptedText = decrypt(ciphertext, privateKeyBytes);
	System.out.println('Decrypted Text: ' + new String(decryptedText, StandardCharsets.UTF_8));

	// 签名和验证
	String message = 'Hello, World!';
	byte[] signature = sign(message.getBytes(StandardCharsets.UTF_8), privateKeyBytes);
	boolean isValid = verify(message.getBytes(StandardCharsets.UTF_8), signature, publicKeyBytes);
	System.out.println('Signature Valid: ' + isValid);
}

原文地址: https://www.cveoy.top/t/topic/phaD 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录