2022年7月

一、分析:

https://blog.csdn.net/weixin_44717746/article/details/106651480

二、总结:

  我们知道在没有面向对象编程语言的时候,我们都是用面向过程的方式来编写程序的,典型的就有C语言,Fortran等等,面向对象的思想,无疑带来了编程思维的一个新的飞跃,但因为多增加一层抽象,也面临着性能问题,典型的就是内存问题。

  面向对象编程,主要围绕着三大特性,封装,继承,多态来实现的,主要的实现方式多以基于类来实现。我们在实例化类的时候,一般会定义一个变量引用我们实例化的对象,引用,即代表着这个变量存放的不是这个实例化的对象,而是这个对象内存首地址,进而达到间接访问的目的。

  在这里,要谈到两个概念,栈和堆,栈一般来说,指的是cpu内部中的寄存器(Register)空间,而堆指的是电脑中的主存(Random Access Memory)。我们在定义一般变量的时候,变量会存放在栈中,而实例化的类会存放在堆中,因此我们要访问堆中的类时,我们要先在栈中提取该类的引用变量得到类的内存地址,进而访问到类中的数据,进行读,写操作。

  但其实一般来说,定义的变量和类的多少是人来决定的,机器的内存大小也就那样,因此,内存分配的工作主要由编译器(或者解释器)的算法来实现的,大概原理是把cpu的寄存器,缓存(cache),内存映射到虚拟内存列表上,再由算法分配最常使用的变量优先以快到慢的存储介质中存放,但类都是放在内存中的。

  现在2022年了,大部分的用户内存都处于16G,32G这个范围,而cpu的寄存器,就算比较牛逼最新的i7 8,9系cpu,也不过个位数的KB大小,cache可能还好一点,几MB到十几MB的大小已经是不错的了,速度大概是内存的5到10倍把,主要涉及到公式1/r+(1-r)h,其中h为Nc/Nc+Nm,Nc为cache存取的次数,Nm为内存存取次数,h为cache命中率,可以知道为了提高命中率,5到10是比较合理的。可想而知,栈内存的空间是如此地稀缺,因此合理地运用栈内存,是可以提高程序的速度的。

  所以,在写程序的时候,尽可能地把类相同的函数方法放入父类中,用继承的方式去引用这些公共的方法,把相同的变量放入连接属性中,或者父类中,减少内存中相同的拷贝,是可以节省不少内存的,同时合理编写算法,高效运用栈内存,尽可能地使用局部变量,在作用域结束的时候可以释放栈内存。

一、证书和编码

X.509证书,其核心是根据RFC 5280编码或数字签名的数字文档。
实际上,术语X.509证书通常指的是IETF的PKIX证书和X.509 v3证书标准的CRL 文件,即如RFC 5280(通常称为PKIX for Public Key Infrastructure(X.509))中规定的。

二、X509文件扩展

我们首先要了解的是每种类型的文件扩展名。 很多人不清楚DER,PEM,CRT和CER结尾的文件是什么,更有甚者错误地说是可以互换的。 在某些情况下,某些可以互换,最佳做法是识别证书的编码方式,然后正确标记。 正确标签的证书将更容易操纵

三、编码--决定扩展名方式

1).DER 扩展名

.DER = DER扩展用于二进制DER编码证书。

这些文件也可能承载CER或CRT扩展。 正确的说法是“我有一个DER编码的证书”不是“我有一个DER证书”。

2).PEM 扩展名

.PEM = PEM扩展用于不同类型的X.509v3文件,是以“ - BEGIN ...”前缀的ASCII(Base64)数据。

3)常见的扩展

3.1).CRT 扩展名

.CRT = CRT扩展用于证书。 证书可以被编码为二进制DER或ASCII PEM。 CER和CRT扩展几乎是同义词。 最常见的于Unix 或类Unix系统。

3.2).CER扩展名

CER = .crt的替代形式(Microsoft Convention)您可以在微软系统环境下将.crt转换为.cer(.both DER编码的.cer,或base64 [PEM]编码的.cer)。

可参考:https://support.comodo.com/index.php?/Knowledgebase/Article/View/361/17/how-do-i-convert-crt-file-into-the-microsoft-cer-format

.cer文件扩展名也被IE识别为 一个运行MS cryptoAPI命令的命令(特别是rundll32.exe cryptext.dll,CryptExtOpenCER),该命令显示用于导入和/或查看证书内容的对话框。

3.3).KEY 扩展名

.KEY = KEY扩展名用于公钥和私钥PKCS#8。 键可以被编码为二进制DER或ASCII PEM。

四、常见的OpenSSL证书操作

证书操作有四种基本类型。查看,转换,组合和提取。

1)查看证书

即使PEM编码的证书是ASCII,它们是不可读的。这里有一些命令可以让你以可读的形式输出证书的内容;

1.1)查看PEM编码证书

openssl x509 -in cert.pem -text -noout
openssl x509 -in cert.cer -text -noout
openssl x509 -in cert.crt -text -noout

如果您遇到这个错误,这意味着您正在尝试查看DER编码的证书,并需要使用“查看DER编码证书”中的命令。

unable to load certificate
12626:error:0906D06C:PEMroutines:PEM_read_bio:no start line:pem_lib.c:647:Expecting: TRUSTEDCERTIFICATE

1.2)查看DER编码证书

openssl x509 -in certificate.der -inform der -text -noout

如果您遇到以下错误,则表示您尝试使用DER编码证书的命令查看PEM编码证书。在“查看PEM编码的证书”中使用命令

unable to load certificate
13978:error:0D0680A8:asn1 encodingroutines:ASN1_CHECK_TLEN:wrong tag:tasn_dec.c:1306:
13978:error:0D07803A:asn1 encodingroutines:ASN1_ITEM_EX_D2I:nested asn1 error:tasn_dec.c:380:Type=X509

2)转换证书格式

转换可以将一种类型的编码证书存入另一种。(即PEM到DER转换)
PEM到DER

openssl x509 -in cert.crt -outform der-out cert.der

DER到PEM

openssl x509 -in cert.crt -inform der -outform pem -out cert.pem

3)组合证书

在某些情况下,将多个X.509基础设施组合到单个文件中是有利的。一个常见的例子是将私钥和公钥两者结合到相同的证书中。

组合密钥和链的最简单的方法是将每个文件转换为PEM编码的证书,然后将每个文件的内容简单地复制到一个新文件中。这适用于组合文件以在Apache中使用的应用程序。

4)证书提取

一些证书将以组合形式出现。 一个文件可以包含以下任何一个:证书,私钥,公钥,签名证书,证书颁发机构(CA)和/或权限链。

if (!in_array('sm4-cbc', openssl_get_cipher_methods())) {
    printf("不支持 sm4\n");
}

$key = 'her-cat.com';
$iv = random_bytes(openssl_cipher_iv_length('sm4-cbc'));

$plaintext = '她和她的猫';

$ciphertext = openssl_encrypt($plaintext, 'sm4-cbc', $key, OPENSSL_RAW_DATA , $iv);

printf("加密结果: %s\n", bin2hex($ciphertext));

$original_plaintext = openssl_decrypt($ciphertext, 'sm4-cbc', $key, OPENSSL_RAW_DATA , $iv);

printf("解密结果: %s\n", $original_plaintext);

结果如下:

加密结果: 45cd787b0a84603ae8fd443b81af4d17
解密结果: 她和她的猫


转载:https://her-cat.com/2021/08/23/php-openssl-sm4.html

CURLINFO_EFFECTIVE_URL - 最后一个有效的URL地址
CURLINFO_HTTP_CODE - 最后一个收到的HTTP代码
CURLINFO_FILETIME - 远程获取文档的时间,如果无法获取,则返回值为"-1"
CURLINFO_TOTAL_TIME - 最后一次传输所消耗的时间
CURLINFO_NAMELOOKUP_TIME - 名称解析所消耗的时间
CURLINFO_CONNECT_TIME - 建立连接所消耗的时间
CURLINFO_PRETRANSFER_TIME - 从建立连接到准备传输所使用的时间
CURLINFO_STARTTRANSFER_TIME - 从建立连接到传输开始所使用的时间
CURLINFO_REDIRECT_TIME - 在事务传输开始前重定向所使用的时间
CURLINFO_SIZE_UPLOAD - 上传数据量的总值
CURLINFO_SIZE_DOWNLOAD - 下载数据量的总值
CURLINFO_SPEED_DOWNLOAD - 平均下载速度
CURLINFO_SPEED_UPLOAD - 平均上传速度
CURLINFO_HEADER_SIZE - header部分的大小
CURLINFO_HEADER_OUT - 发送请求的字符串
CURLINFO_REQUEST_SIZE - 在HTTP请求中有问题的请求的大小
CURLINFO_SSL_VERIFYRESULT - 通过设置CURLOPT_SSL_VERIFYPEER返回的SSL证书验证请求的结果
CURLINFO_CONTENT_LENGTH_DOWNLOAD - 从Content-Length: field中读取的下载内容长度
CURLINFO_CONTENT_LENGTH_UPLOAD - 上传内容大小的说明
CURLINFO_CONTENT_TYPE - 下载内容的Content-Type:值,NULL表示服务器没有发送有效的Content-Type: header


担心原文内容不被删除而迷路,特意自我转载一份:

以下是php封装好的类,引入即可使用

<?php
/**
 * 作者:pjp
 * 邮箱:vippjp@163.com
 */
class RSA{
    private $privateKey='';//私钥(用于用户加密)
    private $publicKey='';//公钥(用于服务端数据解密)
 
    public function __construct(){
        $this->privateKey = openssl_pkey_get_private(file_get_contents('php_private.pem'));//私钥,用于加密
        $this->publicKey = openssl_pkey_get_public(file_get_contents('php_public.pem'));//公钥,用于解密
    }
    
    
    /**
     * 私钥加密
     * @param 原始数据 $data
     * @return 密文结果 string
     */
    public function encryptByPrivateKey($data) {
        openssl_private_encrypt($data,$encrypted,$this->privateKey,OPENSSL_PKCS1_PADDING);//私钥加密
        $encrypted = base64_encode($encrypted);//加密后的内容通常含有特殊字符,需要编码转换下,在网络间通过url传输时要注意base64编码是否是url安全的
        return $encrypted;
    }
    
    /**
     * 私钥解密
     * @param 密文数据 $data
     * @return 原文数据结果 string
     */
    public function decryptByPrivateKey($data){
        $data = base64_decode($data);
        openssl_private_decrypt($data,$encrypted,$this->privateKey,OPENSSL_PKCS1_PADDING);//私钥解密
        return $encrypted;
    }
    
    /**
     * 私钥签名
     * @param unknown $data
     */
    public function signByPrivateKey($data){
        openssl_sign($data, $signature, $this->privateKey);
        $encrypted = base64_encode($signature);//加密后的内容通常含有特殊字符,需要编码转换下,在网络间通过url传输时要注意base64编码是否是url安全的
        return $encrypted;
    }
    
    
    /**
     * 公钥加密
     * @param 原文数据 $data
     * @return 加密结果 string
     */
    public function encryptByPublicKey($data) {
        openssl_public_encrypt($data,$decrypted,$this->publicKey,OPENSSL_PKCS1_PADDING);//公钥加密
        return base64_encode($decrypted);
    }
    
    /**
     * 公钥解密
     * @param 密文数据 $data
     * @return 原文结果 string
     */
    public function decryptByPublicKey($data) {
        $data = base64_decode($data);
        openssl_public_decrypt($data,$decrypted,$this->publicKey,OPENSSL_PKCS1_PADDING);//公钥解密
        return $decrypted;
    }
    
    /**
     * 公钥验签
     * @param unknown $data
     * @param unknown $sign
     */
    public function verifyByPublicKey($data,$sign){
        $sign = base64_decode($sign);
        return openssl_verify($data, $sign, $this->publicKey);
    }
    
    public function __destruct(){
        openssl_free_key($this->privateKey);
        openssl_free_key($this->publicKey);
    }
}

php公钥文件内容(php_public.pem)

公钥和私钥皆可自己重新生成

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCm1YchJdHVy9iXsDfQfMEB2mdO
5wuaEiqUEerHO7HbKKkvhuIfc7haQV5bKTiKZ76FnkkXJMF+onMrQrrqk4TiWlYZ
oilesPM88jr01Z9MmhzKV7vWboVhYcd8cw2Mua0HwAMyl9TDt5OLWmT00C4/Lu72
lRL21avxRTvmDQoAqQIDAQAB
-----END PUBLIC KEY-----

php私钥文件内容(php_private.pem)

-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKbVhyEl0dXL2Jew
N9B8wQHaZ07nC5oSKpQR6sc7sdsoqS+G4h9zuFpBXlspOIpnvoWeSRckwX6icytC
uuqThOJaVhmiKV6w8zzyOvTVn0yaHMpXu9ZuhWFhx3xzDYy5rQfAAzKX1MO3k4ta
ZPTQLj8u7vaVEvbVq/FFO+YNCgCpAgMBAAECgYB1x4s1eJiyAc4wEITm2Bv+Lez/
BBfptmd+z0NbUiZW3VbLqcLbh3ufpERzwR8cfu8/L6bUAuvjddYutVZ2Ip0Nd7dG
5rrktH+7R8UT89fn87bUa5NlLee+egyoz/PJ63X4JjEg5OJbkXMbK4YrTypS0IAx
nZv+7BeSsCrzNlpWAQJBANgmHMDNrIWvU3qVf7u8SS/g+WrlvKMWOXtYjH2OqWoO
Vtmh4Or1PbaPIMnPAXFYiYYW8wcLYnVmVCez5qaysWkCQQDFl9XONZIMFAvdJ5S2
UFk63bEYtCroKZjddTlE6K/j+Vj2IaCFm94i4x1YzJR0KrykrtBTLRi7nuWmdJMJ
r61BAkA7dxDGAk+KX9fJi8OedIh2AaDcxeOFwqGBy7Sq/kqhgNxn918XhOy7gtj0
bFzrP/5lw36M25b00XgpjBbSmaqxAkBnBN/TUHjh1T3OQ0m0uDWdjGI+KAlK3A04
QVrng43ZBXMNeMDRiE+Lzu/JEXjBDFsoXYB+LT/86j5/x721yiNBAkEAgi0F5BvA
wYZQXqAx3iyuj8R9uUKpLePafyBRHnLNrFux2VD0ZX3pXCmfDDmtM/NMO491dI84
6NbVOvxWcNPQ/Q==
-----END PRIVATE KEY-----


以下是java封装好的方法

/**
 * 作者:pjp
 * 邮箱:vippjp@163.com
 */
 package crypt;
 
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.security.KeyFactory;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
 
import javax.crypto.Cipher;
 
public class Rsa {
    
    private String priKey;
    private String pubKey;
    
    public static void main(String[] args) {
        Rsa rsa = new Rsa();
        String str = "我要加密这段文字。";
        System.out.println("原文:"+"我要加密这段文字。");
        String crypt = rsa.encryptByPrivateKey(str);
        System.out.println("私钥加密密文:"+crypt);
        String result = rsa.decryptByPublicKey(crypt);
        System.out.println("原文:"+result);
        
        System.out.println("---");
        
        str = "我要加密这段文字。";
        System.out.println("原文:"+"我要加密这段文字。");
        crypt = rsa.encryptByPublicKey(str);
        System.out.println("公钥加密密文:"+crypt);
        result = rsa.decryptByPrivateKey(crypt);
        System.out.println("原文:"+result);
        
        System.out.println("---");
        
        str = "我要签名这段文字。";
        System.out.println("原文:"+str);
        String str1 = rsa.signByPrivateKey(str);
        System.out.println("签名结果:"+str1);
        if(rsa.verifyByPublicKey(str1, str)){
            System.out.println("成功");
        } else {
            System.out.println("失败");
        }
    }
 
    public Rsa(){
        priKey = readStringFromFile("java_private.pem");
        pubKey = readStringFromFile("java_public.pem");
    }
    
      /**
       * 使用私钥加密
       * @see decByPriKey
       */
      public String encryptByPrivateKey(String data) {
        // 加密
        String str = "";
        try {
            byte[] pribyte = base64decode(priKey.trim());
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pribyte);
            KeyFactory fac = KeyFactory.getInstance("RSA");
            RSAPrivateKey privateKey = (RSAPrivateKey) fac.generatePrivate(keySpec);
            Cipher c1 = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            c1.init(Cipher.ENCRYPT_MODE, privateKey);
            str = base64encode(c1.doFinal(data.getBytes()));
        } catch (Exception e) {
            e.printStackTrace();
            
        }
        return str;
      }
      
      /**
       * 使用私钥解密
       * @see decByPriKey
       */
      public String decryptByPrivateKey(String data) {
        // 加密
        String str = "";
        try {
            byte[] pribyte = base64decode(priKey.trim());
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pribyte);
            KeyFactory fac = KeyFactory.getInstance("RSA");
            RSAPrivateKey privateKey = (RSAPrivateKey) fac.generatePrivate(keySpec);
            Cipher c1 = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            c1.init(Cipher.DECRYPT_MODE, privateKey);
            byte[] temp = c1.doFinal(base64decode(data));
            str = new String(temp);
        } catch (Exception e) {
            e.printStackTrace();
            
        }
        return str;
      }
 
      
      /**
       * 使用公钥加密
       * @see decByPriKey
       */
      public String encryptByPublicKey(String data) {
        // 加密
        String str = "";
        try {
            byte[] pubbyte = base64decode(pubKey.trim());
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pubbyte);
            KeyFactory fac = KeyFactory.getInstance("RSA");
            RSAPublicKey rsaPubKey = (RSAPublicKey) fac.generatePublic(keySpec);
            Cipher c1 = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            c1.init(Cipher.ENCRYPT_MODE, rsaPubKey);
            str = base64encode(c1.doFinal(data.getBytes()));
        } catch (Exception e) {
            e.printStackTrace();
            
        }
        return str;
      }
      
      /**
       * 使用公钥解密
       * @see decByPriKey
       */
      public String decryptByPublicKey(String data) {
        // 加密
        String str = "";
        try {
            byte[] pubbyte = base64decode(pubKey.trim());
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pubbyte);
            KeyFactory fac = KeyFactory.getInstance("RSA");
            RSAPublicKey rsaPubKey = (RSAPublicKey) fac.generatePublic(keySpec);
            Cipher c1 = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            c1.init(Cipher.DECRYPT_MODE, rsaPubKey);
            byte[] temp = c1.doFinal(base64decode(data));
            str = new String(temp);
        } catch (Exception e) {
            e.printStackTrace();
            
        }
        return str;
      }
    /**
     * 本方法使用SHA1withRSA签名算法产生签名
     * @param String src 签名的原字符串
     * @return String 签名的返回结果(16进制编码)。当产生签名出错的时候,返回null。
     */
    public String signByPrivateKey(String src) {
        try {
            Signature sigEng = Signature.getInstance("SHA1withRSA");
            byte[] pribyte = base64decode(priKey.trim());
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pribyte);
            KeyFactory fac = KeyFactory.getInstance("RSA");
            RSAPrivateKey privateKey = (RSAPrivateKey) fac.generatePrivate(keySpec);
            sigEng.initSign(privateKey);
            sigEng.update(src.getBytes());
            byte[] signature = sigEng.sign();
            return base64encode(signature);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
 
    /**
     * 使用共钥验证签名
     * @param sign
     * @param src
     * @return
     */
    public boolean verifyByPublicKey(String sign, String src) {
        try {
            Signature sigEng = Signature.getInstance("SHA1withRSA");
            byte[] pubbyte = base64decode(pubKey.trim());
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pubbyte);
            KeyFactory fac = KeyFactory.getInstance("RSA");
            RSAPublicKey rsaPubKey = (RSAPublicKey) fac.generatePublic(keySpec);
            sigEng.initVerify(rsaPubKey);
            sigEng.update(src.getBytes());
            byte[] sign1 = base64decode(sign);
            return sigEng.verify(sign1);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
 
    /**
     *  base64加密
     * @param bstr
     * @return
     */
    @SuppressWarnings("restriction")
    private String base64encode(byte[] bstr) {
        String str =  new sun.misc.BASE64Encoder().encode(bstr);
        str = str.replaceAll("\r\n", "").replaceAll("\r", "").replaceAll("\n", "");
        return str;
    }
 
    /**
     * base64解密
     * @param str
     * @return byte[]
     */
    @SuppressWarnings("restriction")
    private byte[] base64decode(String str) {
        byte[] bt = null;
        try {
            sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder();
            bt = decoder.decodeBuffer(str);
        } catch (IOException e) {
            e.printStackTrace();
        }
 
        return bt;
    }
 
    /**
     * 从文件中读取所有字符串
     * @param fileName
     * @return    String
     */
    private String readStringFromFile(String fileName){
        StringBuffer str = new StringBuffer();
        try {
            File file = new File(fileName);
            FileReader fr = new FileReader(file);
            char[] temp = new char[1024];
            while (fr.read(temp) != -1) {
                str.append(temp);
            }
            fr.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
 
        }
        return str.toString();
    }
}

java公钥文件内容(java_public.pem)

MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCm1YchJdHVy9iXsDfQfMEB2mdO
5wuaEiqUEerHO7HbKKkvhuIfc7haQV5bKTiKZ76FnkkXJMF+onMrQrrqk4TiWlYZ
oilesPM88jr01Z9MmhzKV7vWboVhYcd8cw2Mua0HwAMyl9TDt5OLWmT00C4/Lu72
lRL21avxRTvmDQoAqQIDAQAB

java私钥文件内容(java_private.pem)

MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKbVhyEl0dXL2Jew
N9B8wQHaZ07nC5oSKpQR6sc7sdsoqS+G4h9zuFpBXlspOIpnvoWeSRckwX6icytC
uuqThOJaVhmiKV6w8zzyOvTVn0yaHMpXu9ZuhWFhx3xzDYy5rQfAAzKX1MO3k4ta
ZPTQLj8u7vaVEvbVq/FFO+YNCgCpAgMBAAECgYB1x4s1eJiyAc4wEITm2Bv+Lez/
BBfptmd+z0NbUiZW3VbLqcLbh3ufpERzwR8cfu8/L6bUAuvjddYutVZ2Ip0Nd7dG
5rrktH+7R8UT89fn87bUa5NlLee+egyoz/PJ63X4JjEg5OJbkXMbK4YrTypS0IAx
nZv+7BeSsCrzNlpWAQJBANgmHMDNrIWvU3qVf7u8SS/g+WrlvKMWOXtYjH2OqWoO
Vtmh4Or1PbaPIMnPAXFYiYYW8wcLYnVmVCez5qaysWkCQQDFl9XONZIMFAvdJ5S2
UFk63bEYtCroKZjddTlE6K/j+Vj2IaCFm94i4x1YzJR0KrykrtBTLRi7nuWmdJMJ
r61BAkA7dxDGAk+KX9fJi8OedIh2AaDcxeOFwqGBy7Sq/kqhgNxn918XhOy7gtj0
bFzrP/5lw36M25b00XgpjBbSmaqxAkBnBN/TUHjh1T3OQ0m0uDWdjGI+KAlK3A04
QVrng43ZBXMNeMDRiE+Lzu/JEXjBDFsoXYB+LT/86j5/x721yiNBAkEAgi0F5BvA
wYZQXqAx3iyuj8R9uUKpLePafyBRHnLNrFux2VD0ZX3pXCmfDDmtM/NMO491dI84
6NbVOvxWcNPQ/Q==

说明:

java和php的RSA加解密版本已全部通过测试。并且可以相互加解密。
私钥是服务器保留,公钥可以发放给对应的客户端,甚至可以是公共的。
采用私钥加密-》公钥解密 和 公钥加密-》私钥解密 的加密方式。
但是如果客户端是需要更高安全性的支付系统,那么应该采用两对密钥。
每一方分别是自己的私钥和对方的公钥,采用私钥加密并签名-》公钥解密并验签的方式。

注意:给出的是两个版本的两对密钥,实际上只是一对密钥。区别是java的密钥去掉了头尾注释。而PHP的密钥保留了头尾注释。

————————————————
版权声明:本文为CSDN博主「蝶开三月」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/panjiapengfly/article/details/75318930