package com.wechat.v3;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.Base64;
public class EncryptionUtil {
private static final String TRANSFORMATION = "RSA/ECB/OAEPWithSHA-1AndMGF1Padding";
public static String encryptOAEP(String message, X509Certificate certificate) throws IllegalBlockSizeException {
return encrypt(message, certificate, TRANSFORMATION);
}
public static String encrypt(String message, X509Certificate certificate, String transformation) throws IllegalBlockSizeException {
try {
Cipher cipher = Cipher.getInstance(transformation);
cipher.init(Cipher.ENCRYPT_MODE, certificate.getPublicKey());
byte[] data = message.getBytes(StandardCharsets.UTF_8);
byte[] ciphertext = cipher.doFinal(data);
return Base64.getEncoder().encodeToString(ciphertext);
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
throw new RuntimeException("当前Java环境不支持RSA v1.5/OAEP", e);
} catch (InvalidKeyException e) {
throw new IllegalArgumentException("无效的证书", e);
} catch (IllegalBlockSizeException | BadPaddingException e) {
throw new IllegalBlockSizeException("加密原串的长度不能超过214字节");
}
}
}
<?php declare(strict_types=1);
namespace WeChatPay\Crypto;
use const OPENSSL_PKCS1_OAEP_PADDING;
use const OPENSSL_PKCS1_PADDING;
use function base64_encode;
use function openssl_public_encrypt;
use function sprintf;
use UnexpectedValueException;
class Rsa
{
private static function paddingModeLimitedCheck(int $padding): void
{
if (!($padding === OPENSSL_PKCS1_OAEP_PADDING || $padding === OPENSSL_PKCS1_PADDING)) {
throw new UnexpectedValueException(sprintf("Doesn't supported padding mode(%d), here only support OPENSSL_PKCS1_OAEP_PADDING or OPENSSL_PKCS1_PADDING.", $padding));
}
}
public static function encrypt(string $plaintext, $publicKey, int $padding = OPENSSL_PKCS1_OAEP_PADDING): string
{
self::paddingModeLimitedCheck($padding);
if (!openssl_public_encrypt($plaintext, $encrypted, $publicKey, $padding)) {
throw new UnexpectedValueException('Encrypting the input $plaintext failed, please checking your $publicKey whether or nor correct.');
}
return base64_encode($encrypted);
}
}
package wechatpay
import (
"crypto/rand"
"crypto/rsa"
"crypto/sha1"
"crypto/x509"
"encoding/base64"
"fmt"
)
// EncryptOAEPWithPublicKey 使用 OAEP padding方式用公钥进行加密
func EncryptOAEPWithPublicKey(message string, publicKey *rsa.PublicKey) (ciphertext string, err error) {
if publicKey == nil {
return "", fmt.Errorf("you should input *rsa.PublicKey")
}
ciphertextByte, err := rsa.EncryptOAEP(sha1.New(), rand.Reader, publicKey, []byte(message), nil)
if err != nil {
return "", fmt.Errorf("encrypt message with public key err:%s", err.Error())
}
ciphertext = base64.StdEncoding.EncodeToString(ciphertextByte)
return ciphertext, nil
}
// EncryptOAEPWithCertificate 先解析出证书中的公钥,然后使用 OAEP padding方式公钥进行加密
func EncryptOAEPWithCertificate(message string, certificate *x509.Certificate) (ciphertext string, err error) {
if certificate == nil {
return "", fmt.Errorf("you should input *x509.Certificate")
}
publicKey, ok := certificate.PublicKey.(*rsa.PublicKey)
if !ok {
return "", fmt.Errorf("certificate is invalid")
}
return EncryptOAEPWithPublicKey(message, publicKey)
}
// EncryptPKCS1v15WithPublicKey 使用PKCS1 padding方式用公钥进行加密
func EncryptPKCS1v15WithPublicKey(message string, publicKey *rsa.PublicKey) (ciphertext string, err error) {
if publicKey == nil {
return "", fmt.Errorf("you should input *rsa.PublicKey")
}
ciphertextByte, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, []byte(message))
if err != nil {
return "", fmt.Errorf("encrypt message with public key err:%s", err.Error())
}
ciphertext = base64.StdEncoding.EncodeToString(ciphertextByte)
return ciphertext, nil
}
// EncryptPKCS1v15WithCertificate 先解析出证书中的公钥,然后使用PKCS1 padding方式用公钥进行加密
func EncryptPKCS1v15WithCertificate(message string, certificate *x509.Certificate) (ciphertext string, err error) {
if certificate == nil {
return "", fmt.Errorf("you should input *x509.Certificate")
}
publicKey, ok := certificate.PublicKey.(*rsa.PublicKey)
if !ok {
return "", fmt.Errorf("certificate is invalid")
}
return EncryptPKCS1v15WithPublicKey(message, publicKey)
}