为了保证通信过程中敏感信息字段(如用户的住址、银行卡号、手机号码等)的机密性,微信支付API v3要求商户对上送的敏感信息字段进行加密。与之相对应,微信支付会对下行的敏感信息字段进行加密,商户需解密后方能得到原文。下面详细介绍加解密的方式,以及如何进行相应的计算。 
我们提供了微信支付API v3官方SDK(目前包含 Java 、 PHP 、 Go 三种语言版本),使用官方 SDK 调用微信支付接口,无需关心签名生成和验证,接入更方便。 
使用平台证书加密,需要在http请求增加一个Wechatpay-Serial请求头,并传入平台证书序列号"Wechatpay-Serial: 4A4EF961F12345D888A902944179F1F270FC68B3"(此处的平台证书序列号只是一个示例,每个商户号的平台证书序列号不一样,需传入商户号对应的平台证书序列号) 
1. 加密算法 敏感信息加密使用的 RSA公钥加密算法 。加密算法使用的填充方案,我们使用了相对更安全的RSAES-OAEP(Optimal Asymmetric Encryption Padding)。 
OpenSSL ,padding设置为 RSA_PKCS1_OAEP_PADDING 
Java,使用 Cipher.getinstance(RSA/ECB/OAEPWithSHA-1AndMGF1Padding) 
PHP ,padding设置为 OPENSSL_PKCS1_OAEP_PADDING 
.NET ,fOAEP设置为true 
Node.js ,padding设置为 crypto.constants.RSA_PKCS1_OAEP_PADDING 
GO ,使用 EncryptOAEP 
开发者应当使用微信支付平台证书中的公钥,对上送的敏感信息进行加密。这样只有拥有私钥的微信支付才能对密文进行解密,从而保证了信息的机密性。 
另一方面,微信支付使用 商户证书中的公钥对下行的敏感信息进行加密。开发者应使用商户私钥对下行的敏感信息的密文进行解密。 
2. 加密示例 开发者应当使用微信支付平台证书中的公钥,对上送的敏感信息进行加密。 
大部分编程语言支持RSA公钥加密。你可以参考示例,了解如何使用您的编程语言实现敏感信息加密。 
1 public   static   String   rsaEncryptOAEP ( String   message ,   X509Certificate   certificate ) 
 2 throws   IllegalBlockSizeException ,   IOException   { 
 3    try   { 
 4      Cipher   cipher   =   Cipher . getInstance ( "RSA/ECB/OAEPWithSHA-1AndMGF1Padding" ) ; 
 5      cipher . init ( Cipher . ENCRYPT_MODE ,   certificate . getPublicKey ( ) ) ; 
 6      byte [ ]   data   =   message . getBytes ( "utf-8" ) ; 
 7      byte [ ]   cipherdata   =   cipher . doFinal ( data ) ; 
 8      return   Base64 . getEncoder ( ) . encodeToString ( cipherdata ) ; 
 9    }   catch   ( NoSuchAlgorithmException   |   NoSuchPaddingException   e )   { 
 10      throw   new   RuntimeException ( "当前Java环境不支持RSA v1.5/OAEP" ,   e ) ; 
 11    }   catch   ( InvalidKeyException   e )   { 
 12      throw   new   IllegalArgumentException ( "无效的证书" ,   e ) ; 
 13    }   catch   ( IllegalBlockSizeException   |   BadPaddingException   e )   { 
 14      throw   new   IllegalBlockSizeException ( "加密原串的长度不能超过214字节" ) ; 
 15    } 
 16 } 1 secretMessage   : =   [ ] byte ( "send reinforcements, we're going to advance" ) 
 2 rng   : =   rand . Reader 
 3 cipherdata ,   err   : =   EncryptOAEP ( sha1 . New ( ) ,   rng ,   rsaPublicKey ,   secretMessage ,   nil ) 
 4 if   err   !=   nil   { 
 5          fmt . Fprintf ( os . Stderr ,   "Error from encryption: %s\n" ,   err ) 
 6          return 
 7 } 
 8 ciphertext   : =   base64 . StdEncoding . EncodeToString ( cipherdata ) 
 9 fmt . Printf ( "Ciphertext: %s\n" ,   ciphertext ) 1 private 
 2 function   getEncrypt ( $str )   { 
 3    
 4    $public_key_path   =   '平台证书路径' ; 
 5    $public_key   =   file_get_contents ( $public_key_path ) ; 
 6    $encrypted   =   '' ; 
 7    if   ( openssl_public_encrypt ( $str ,   $encrypted ,   $public_key ,   OPENSSL_PKCS1_OAEP_PADDING ) )   { 
 8      
 9      $sign   =   base64_encode ( $encrypted ) ; 
 10    }   else   { 
 11      throw   new   Exception ( 'encrypt failed' ) ; 
 12    } 
 13    return   $sign ; 
 14 } 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 public   static   string   RSAEncrypt ( string   text ,   byte [ ]   publicKey ) 
 11 { 
 12      using   ( var   x509   =   new   X509Certificate2 ( publicKey ) ) 
 13      { 
 14          using   ( var   rsa   =   ( RSACryptoServiceProvider ) x509 . PublicKey . Key ) 
 15          { 
 16              var   buff   =   rsa . Encrypt ( Encoding . UTF8 . GetBytes ( text ) ,   true ) ; 
 17              return   Convert . ToBase64String ( buff ) ; 
 18          } 
 19      } 
 20 }