视频一区二区三区自拍_千金肉奴隷1985未删减版在线观看_国产成人黄色视频在线播放_少女免费播放片高清在线观看_国产精品v欧美精品v

Login expired. Please log in again.

Feedback

0/300

Feedback

Submitted successfully

ok

Feedback

Network exception, please try again later

ok

敏感信息加解密

為了保證通信過(guò)程中敏感信息字段(如用戶(hù)的住址、銀行卡號(hào)、手機(jī)號(hào)碼等)的機(jī)密性,微信支付API V3要求商戶(hù)對(duì)上送的敏感信息字段進(jìn)行加密。與之相對(duì)應(yīng),微信支付會(huì)對(duì)下行的敏感信息字段進(jìn)行加密,商戶(hù)需解密后方能得到原文。下面詳細(xì)介紹加解密的方式,以及如何進(jìn)行相應(yīng)的計(jì)算。

1. 加密算法

敏感信息加密使用的RSA公鑰加密算法。加密算法使用的填充方案,我們使用了相對(duì)更安全的RSAES-OAEP(Optimal Asymmetric Encryption Padding)。

RSAES-OAEP在各個(gè)編程語(yǔ)言中的模式值為:

? OpenSSL,padding設(shè)置為RSA_PKCS1_OAEP_PADDING

? Java,使用Cipher.getinstance(RSA/ECB/OAEPWithSHA-1AndMGF1Padding)

? PHP,padding設(shè)置為OPENSSL_PKCS1_OAEP_PADDING

? .NET,fOAEP設(shè)置為true

? Node.js,padding設(shè)置為crypto.constants.RSA_PKCS1_OAEP_PADDING

? Go,使用EncryptOAEP

開(kāi)發(fā)者應(yīng)當(dāng)使用微信支付平臺(tái)證書(shū)中的公鑰,對(duì)上送的敏感信息進(jìn)行加密。這樣只有擁有私鑰的微信支付才能對(duì)密文進(jìn)行解密,從而保證了信息的機(jī)密性。

另一方面,微信支付使用 商戶(hù)證書(shū)中的公鑰對(duì)下行的敏感信息進(jìn)行加密。開(kāi)發(fā)者應(yīng)使用商戶(hù)私鑰對(duì)下行的敏感信息的密文進(jìn)行解密。

2. 加密示例

開(kāi)發(fā)者應(yīng)當(dāng)使用 微信支付平臺(tái)證書(shū)中的公鑰,對(duì)上送的敏感信息進(jìn)行加密。

大部分編程語(yǔ)言支持RSA公鑰加密。你可以參考示例,了解如何使用您的編程語(yǔ)言實(shí)現(xiàn)敏感信息加密。

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("當(dāng)前Java環(huán)境不支持RSA v1.5/OAEP", e);
} catch (InvalidKeyException e) {
throw new IllegalArgumentException("無(wú)效的證書(shū)", e);
} catch (IllegalBlockSizeException | BadPaddingException e) {
throw new IllegalBlockSizeException("加密原串的長(zhǎng)度不能超過(guò)214字節(jié)");
}
}
}
<?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方式用公鑰進(jìn)行加密
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 先解析出證書(shū)中的公鑰,然后使用 OAEP padding方式公鑰進(jìn)行加密
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方式用公鑰進(jìn)行加密
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 先解析出證書(shū)中的公鑰,然后使用PKCS1 padding方式用公鑰進(jìn)行加密
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)
}

3. 聲明加密使用的平臺(tái)證書(shū)

某些情況下,微信支付會(huì)更新平臺(tái)證書(shū)。這時(shí),商戶(hù)有多個(gè)微信支付平臺(tái)證書(shū)可以用于加密。為了保證解密順利,商戶(hù)發(fā)起請(qǐng)求的HTTP頭部中應(yīng)包括RSA公鑰加密算法,以聲明加密所用的密鑰對(duì)和證書(shū)。

? 商戶(hù)上送敏感信息時(shí)使用微信支付平臺(tái)公鑰加密,證書(shū)序列號(hào)包含在請(qǐng)求HTTP頭部的Wechatpay-Serial

4. 解密示例

微信支付使用商戶(hù)證書(shū)中的公鑰對(duì)下行的敏感信息進(jìn)行加密。開(kāi)發(fā)者應(yīng)使用商戶(hù)私鑰對(duì)下行的敏感信息的密文進(jìn)行解密。

同樣的,大部分編程語(yǔ)言支持RSA私鑰解密。你可以參考示例,了解如何使用您的編程語(yǔ)言實(shí)現(xiàn)敏感信息解密。

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.PrivateKey;
import java.util.Base64;

public class DecryptionUtil {

    private static final String TRANSFORMATION = "RSA/ECB/OAEPWithSHA-1AndMGF1Padding";

    public static String decryptOAEP(String ciphertext, PrivateKey privateKey) throws BadPaddingException {
        return decrypt(ciphertext, privateKey, TRANSFORMATION);
    }

    public static String decrypt(String ciphertext, PrivateKey privateKey, String transformation) throws BadPaddingException {
        try {
            Cipher cipher = Cipher.getInstance(transformation);
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            byte[] data = Base64.getDecoder().decode(ciphertext);
            return new String(cipher.doFinal(data), StandardCharsets.UTF_8);

        } catch (NoSuchPaddingException | NoSuchAlgorithmException e) {
            throw new RuntimeException("當(dāng)前Java環(huán)境不支持RSA v1.5/OAEP", e);
        } catch (InvalidKeyException e) {
            throw new IllegalArgumentException("無(wú)效的私鑰", e);
        } catch (BadPaddingException | IllegalBlockSizeException e) {
            throw new BadPaddingException("解密失敗");
        }
    }
}
<?php declare(strict_types=1);

namespace WeChatPay\Crypto;

use const OPENSSL_PKCS1_OAEP_PADDING;
use const OPENSSL_PKCS1_PADDING;
use function base64_decode;
use function openssl_private_decrypt;
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 decrypt(string $ciphertext, $privateKey, int $padding = OPENSSL_PKCS1_OAEP_PADDING): string
    {
        self::paddingModeLimitedCheck($padding);

        if (!openssl_private_decrypt(base64_decode($ciphertext), $decrypted, $privateKey, $padding)) {
            throw new UnexpectedValueException('Decrypting the input $ciphertext failed, please checking your $privateKey whether or nor correct.');
        }

        return $decrypted;
    }
}
package wechatpay

import (
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha1"
	"encoding/base64"
	"fmt"
)

// DecryptOAEP 使用私鑰進(jìn)行解密
func DecryptOAEP(ciphertext string, privateKey *rsa.PrivateKey) (message string, err error) {
	if privateKey == nil {
		return "", fmt.Errorf("you should input *rsa.PrivateKey")
	}
	decodedCiphertext, err := base64.StdEncoding.DecodeString(ciphertext)
	if err != nil {
		return "", fmt.Errorf("base64 decode failed, error=%s", err.Error())
	}
	messageBytes, err := rsa.DecryptOAEP(sha1.New(), rand.Reader, privateKey, decodedCiphertext, nil)
	if err != nil {
		return "", fmt.Errorf("decrypt ciphertext with private key err:%s", err)
	}
	return string(messageBytes), nil
}

// DecryptPKCS1v15 使用私鑰對(duì)PKCS1 padding方式加密的字符串進(jìn)行解密
func DecryptPKCS1v15(ciphertext string, privateKey *rsa.PrivateKey) (message string, err error) {
	if privateKey == nil {
		return "", fmt.Errorf("you should input *rsa.PrivateKey")
	}
	decodedCiphertext, err := base64.StdEncoding.DecodeString(ciphertext)
	if err != nil {
		return "", fmt.Errorf("base64 decode failed, error=%s", err.Error())
	}
	messageBytes, err := rsa.DecryptPKCS1v15(rand.Reader, privateKey, decodedCiphertext)
	if err != nil {
		return "", fmt.Errorf("decrypt ciphertext with private key err:%s", err)
	}
	return string(messageBytes), nil
}
    頁(yè)面導(dǎo)航

About  WeChat  Pay

Powered By Tencent & Tenpay Copyright©

2005-2024 Tenpay All Rights Reserved.

Contact Us
Wechat Pay Global

WeChat Pay Global

置頂