java服务端、php、C#客户端rsa

-----------------------------------------------------

最近公司项目需要用到rsa,故对rsa签名算法的一些概念和不同语言的使用进行了研究(具体实现算法则不钻牛角尖了)

------------------------------------------------------------------------------------------

对rsa算法的个人理解

什么是RSA签名、验签、加密解密

1、rsa算法为非对称加密算法,双方保存自己的私钥,并公开自己的公钥
2、双方通信时,都只会用到自己的私钥和对方的公钥
3、签名使用自己的私钥,对方收到签名后,保证数据未丢失或篡改,并且保证数据是从发送方发送而非第三者伪造
4、加密使用对方的公钥,只有对方私钥才能解密,第三者拿到数据也无法解密

常见密钥存在形式

1、文件证书形式,一般为.pfx文件,可以将证书导入浏览器,并导出公钥,公钥一般为.cer文件,本文代码使用字符串格式密钥对,可使用openssl进行生成(网上教程很多),也可以直接在代码中生成。
2、base64转码之后的字符串形式,方便使用,java和c#使用的密钥形式不一样
3、提供modulus+exponent,可从证书中获取这两者,也可由这两者得到密钥,每种语言算法不同

签名算法步骤(验签和加密解密算法类似,详见代码)

1、获取自己的私钥(文件读取、字符串、modulus和exponent生成等方式)
2、将参与签名的字符串转化为byte数组,为了防止乱码,规定所有字符和byte数组转化都使用utf-8编码
3、调用签名方法,每种语言都提供了签名算法中的哈希方式,底层一般是先对字符串进行哈希减少其长度,再进行rsa处理,一般采用md5进行哈希
4、调用各语言的签名方法,得到签名后的byte数组
5、对签名后byte数组进行base64转码,返回结果

对使用rsa的建议

1、一般普通消息只需要进行签名,对于敏感信息,如银行卡信息等则需要进行加密
2、加密消耗相对比较多,所以尽量只对必要数据进行加密,并且尽量将需要加密的数据放到一个字符串中统一加密,避免多次加密
3、rsa能加密的最大字符串长度受密钥本身初始化长度限制,如果必须加密较长数据,要么增加密钥初始化长度、要么采用对加密数据进行分段加密的方式,不同语言之间通讯建议采用第二种
4、理论上,公钥和私钥都可以用来加密解密、签名验签,但是一般规范上,签名和解密一定是使用自己的私钥、加密和验签一定是使用对方的公钥
5、一般数据只进行签名,所以交易过程中,在验证签名通过后,最好再对报文的业务内容进行验证,比如商户号等,以确保此交易确实是从对方发过来
6、asp可通过.net,使用c#或vb实现

三个语言的代码(以下代码可相互签名验签、加密解密)

java版本(base64的需要自己找包)

import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
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 java.util.HashMap;
import java.util.Map;

import javax.crypto.Cipher;

/**
 * RSA加密方法
 * 
 */
public class JavaRSA {

	/**
	 * 加密算法RSA
	 */
	public static final String KEY_ALGORITHM = "RSA";

	/**
	 * 签名算法
	 */
	public static final String SIGNATURE_ALGORITHM = "MD5withRSA";

	/**
	 * 获取公钥的key
	 */
	private static final String PUBLIC_KEY = "RSAPublicKey";

	/**
	 * 获取私钥的key
	 */
	private static final String PRIVATE_KEY = "RSAPrivateKey";

	/**
	 * RSA最大加密明文大小
	 */
	private static final int MAX_ENCRYPT_BLOCK = 116;

	/**
	 * RSA最大解密密文大小
	 */
	private static final int MAX_DECRYPT_BLOCK = 128;

	/**
	 * <p>
	 * 	生成密钥对(公钥和私钥)
	 * </p>
	 * 
	 * @return
	 * @throws Exception
	 */
	public static Map<String, Object> genKeyPair() throws Exception {
		KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
		keyPairGen.initialize(1024);
		KeyPair keyPair = keyPairGen.generateKeyPair();
		RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
		RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
		Map<String, Object> keyMap = new HashMap<String, Object>(2);
		keyMap.put(PUBLIC_KEY, publicKey);
		keyMap.put(PRIVATE_KEY, privateKey);
		return keyMap;
	}

	/**
	 * <P>
	 * 私钥解密
	 * </p>
	 * 
	 * @param encryptedData
	 *            已加密数据
	 * @param privateKey
	 *            私钥(BASE64编码)
	 * @return
	 * @throws Exception
	 */
	public static String decryptByPrivateKey(String encryptedData, String privateKey) throws Exception {
		byte[] keyBytes = Base64.decode(privateKey);
		byte[] encryptedBytes = Base64.decode(encryptedData);
		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(Cipher.DECRYPT_MODE, privateK);
		int inputLen = encryptedBytes.length;
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		int offSet = 0;
		byte[] cache;
		int i = 0;
		// 对数据分段解密
		while (inputLen - offSet > 0) {
			if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
				cache = cipher.doFinal(encryptedBytes, offSet, MAX_DECRYPT_BLOCK);
			} else {
				cache = cipher.doFinal(encryptedBytes, offSet, inputLen - offSet);
			}
			out.write(cache, 0, cache.length);
			i++;
			offSet = i * MAX_DECRYPT_BLOCK;
		}
		byte[] decryptedData = out.toByteArray();
		out.close();
		return new String(decryptedData, "utf-8");
	}

	/**
	 * <p>
	 * 公钥加密
	 * </p>
	 * 
	 * @param data
	 *            源数据
	 * @param publicKey
	 *            公钥(BASE64编码)
	 * @return
	 * @throws Exception
	 */
	public static String encryptByPublicKey(String data, String publicKey) throws Exception {
		byte[] keyBytes = Base64.decode(publicKey);
		byte[] dataBytes = data.getBytes("utf-8");
		X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		Key publicK = keyFactory.generatePublic(x509KeySpec);
		// 对数据加密
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(Cipher.ENCRYPT_MODE, publicK);
		int inputLen = dataBytes.length;
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		int offSet = 0;
		byte[] cache;
		int i = 0;
		// 对数据分段加密
		while (inputLen - offSet > 0) {
			if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
				cache = cipher.doFinal(dataBytes, offSet, MAX_ENCRYPT_BLOCK);
			} else {
				cache = cipher.doFinal(dataBytes, offSet, inputLen - offSet);
			}
			out.write(cache, 0, cache.length);
			i++;
			offSet = i * MAX_ENCRYPT_BLOCK;
		}
		byte[] encryptedData = out.toByteArray();
		out.close();
		return Base64.encode(encryptedData).replaceAll("\n", "").replaceAll("\r\n", "");
	}

	/**
	 * <p>
	 * 私钥签名
	 * </p>
	 * 
	 * @param data
	 *            源数据
	 * @param privateKey
	 *            私钥(BASE64编码)
	 * @return
	 * @throws Exception
	 */
	public static String signByPrivateKey(String data, String privateKey) throws Exception {
		byte[] keyBytes = Base64.decode(privateKey);
		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
		Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
		signature.initSign(privateK);
		signature.update(data.getBytes("utf-8"));
		return Base64.encode(signature.sign()).replaceAll("\n", "").replaceAll("\r\n", "");
	}

	/**
	 * <p>
	 * 公钥验签
	 * </p>
	 * 
	 * @param encryptedData
	 *            已加密数据
	 * @param publicKey
	 *            公钥(BASE64编码)
	 * @return
	 * @throws Exception
	 */
	public static boolean validateSignByPublicKey(String paramStr, String publicKey, String signedData) throws Exception {
		byte[] keyBytes = Base64.decode(publicKey);
		X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		PublicKey publicK = keyFactory.generatePublic(keySpec);
		Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
		signature.initVerify(publicK);
		signature.update(paramStr.getBytes("utf-8"));
		return signature.verify(Base64.decode(signedData));
	}

	/**
	 * <p>
	 * 获取私钥
	 * </p>
	 * 
	 * @param keyMap
	 *            密钥对
	 * @return
	 * @throws Exception
	 */
	public static String getPrivateKey(Map<String, Object> keyMap) throws Exception {
		Key key = (Key) keyMap.get(PRIVATE_KEY);
		return Base64.encode(key.getEncoded()).replaceAll("\r\n", "").replaceAll("\r", "").replaceAll("\n", "");
	}

	/**
	 * <p>
	 * 获取公钥
	 * </p>
	 * 
	 * @param keyMap
	 *            密钥对
	 * @return
	 * @throws Exception
	 */
	public static String getPublicKey(Map<String, Object> keyMap) throws Exception {
		Key key = (Key) keyMap.get(PUBLIC_KEY);
		return Base64.encode(key.getEncoded()).replaceAll("\r\n", "").replaceAll("\r", "").replaceAll("\n", "");
	}
}



asp.net使用c#代码(rsa.aspx)

使用java的文件字符串,需下载开源包进行转换(http://www.bouncycastle.org/csharp/)

<%@ Page Language="C#" codePage="65001"  Debug="true" %>
<%@ import namespace="System" %>
<%@ import namespace="System.Security.Cryptography" %>
<%@ import namespace="System.Text" %>
<%@ import namespace="System.Web" %>
<%@ import namespace="System.IO" %>

<%@ import namespace="System.Xml" %>
<%@ import namespace="Org.BouncyCastle.Asn1.Pkcs" %>
<%@ import namespace="Org.BouncyCastle.Asn1.X509" %>
<%@ import namespace="Org.BouncyCastle.Crypto.Parameters" %>
<%@ import namespace="Org.BouncyCastle.Math" %>
<%@ import namespace="Org.BouncyCastle.Pkcs" %>
<%@ import namespace="Org.BouncyCastle.Security" %>
<%@ import namespace="Org.BouncyCastle.X509" %>

<script runat="server">
string writeStr;
protected void Page_Load(object sender, EventArgs e)
{
//初始值(A代表自己,B代表对方)
//A私钥
string APriKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIqPpXTp0eqvRKLOjDI/EqqbGrpWP6LIiVKbQkLZfdRsZaYBNwwVPVPnIRonA7g4q/p0+G6sVwa4Jt0Xg0vFxXE9yvWqh5dMuxV997DguMeusWk4U8BaCfPKVkBGNJ6NieT7ksEFLydTcnucY3T1TiMPXBcM4x1d8Iv8GW73R9nfAgMBAAECgYA8XAkCnhzgtAsdNQbjmJBEG58QDyRXgC45+wJpZp8m2zWIlDzrmZEGrMfBwb8gECfyyeOzKoYamjvr0iNS7cttPWTFXd4eCrLdJTwR1zFjlWHkRmfkOv34GGneIFLyKcx8YaH35MeNZaz+9XBygGlNRuALJklgLDCoEmV01pY4uQJBAM7DoCIDdA2waumgci5Sdoys08/x38bzk4LBHwkYVxXCb7AEPMy4RS42E89Oyo1dhHsZwySmsE12VhiUZ0scSUsCQQCrjlpcW63g2kys/UBDhSphH6h+82ytNy+KUxUvb2GeOVaE6myF33JJ3yti4WSEp3XN7qWqaZ2kiKCNG8gfbEk9AkBK+gtWajQqRp/uSh09iO+uQXmpfUctaORD1O4BKU9i95fylwbJIcUMZdW3JhYzPwcscIIgB0YFQPUlgqMWTJKTAkEAkrLK0BlRaWoikPaKQnKX16+DnPM5JjF/hJAhGIvs9KjhNA1luWBmUYb1ibtlAg5UrUD6BuwDcpOmfqOYEE6/nQJAef4esNFwU6xsAljgYTol41Tx8f/U8p7YvbF8uaKwhi5NXu8vJJaBWUPqZAi2TWjMNplXLWFMtu686EeNunwv2Q==";
//A公钥
//string APubKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCKj6V06dHqr0SizowyPxKqmxq6Vj+iyIlSm0JC2X3UbGWmATcMFT1T5yEaJwO4OKv6dPhurFcGuCbdF4NLxcVxPcr1qoeXTLsVffew4LjHrrFpOFPAWgnzylZARjSejYnk+5LBBS8nU3J7nGN09U4jD1wXDOMdXfCL/Blu90fZ3wIDAQAB";
//B公钥
string BPubKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCcScNSn+Rhn8j0V1XWbjiFa9Gl5QI2L+F0Tu7jCwCciNA/PVSJrbrgGGQ1HgCPFbkCGyp5cz0cadS+cT3IyDiwqw3cAeWM3brcXnAWEdAyw/EyAMcHtIJQEMUfZDzfrpGeDLziEirf5sNgyXold/kaVoR2huraWOs95Ud3x6o78QIDAQAB";
//B私钥
//string BPriKey = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJxJw1Kf5GGfyPRXVdZuOIVr0aXlAjYv4XRO7uMLAJyI0D89VImtuuAYZDUeAI8VuQIbKnlzPRxp1L5xPcjIOLCrDdwB5YzdutxecBYR0DLD8TIAxwe0glAQxR9kPN+ukZ4MvOISKt/mw2DJeiV3+RpWhHaG6tpY6z3lR3fHqjvxAgMBAAECgYEAgSDg5O9+vrpKSreuEFFZGcOPoEWqoiLFYFenQKfihXL0vItrwaVs9aKxiMGVLKOCDJ9tZJM2NreqMv9VUQM88ks22O8IYfZhQdGkZyNNVRD9C3aDBmpTx4v3WDvQVcfhc0UTX/tZqNivkRkZxLhhOAoBAfzp1hE6tBqeORveSJECQQDviqq13zHp1+Pin7aSQNpzZfqGSjmzY/VqQcOlHVzATkIOXHUayYnDIh/s390Wb8gH6zBa2zLk3hhwb94+gvN3AkEApwa82ixwBoljPgB6saJn2T4OoeykCL+QCatflupTZ/DkVLs2hvb13tRJPHfzTv6MtVGtNbTnh1ZJzB/+K8EV1wJAIfK9Dtl68XEvUsbf0Qpv6zrgrneGhe38sfpwB86JfpeYtQBVeF5nr8f+TkvLwYpGBxlF2RqHs/fl7slr7eARMQJARIlTPQM3BLejbXGs5u8JRe9c+bysoppYdF9J3hdRGjmSt+IKQd9cjI73bkSaJjP1cQGO3ZbZ2oLhzUzjcvjMCQJBAO4ov7Ee0DmLYWX8W89hMK8CYhWxMqVGnpmaaMmzCdv1r+ZK9R4+qDxRHSCrTxczYTuzzLjykqjCh4W3fkJUBH0=";
//加密、签名字符串
string plainText = "test123";
//dinpay签名后字符串
string BSignedData = "LfNb7DnalXxnub4FT3YBxbnRSRlddrG71NyvDP+3FiJgUJg9G/gEKsmI+fHSRAAxaSSXkwEgdNn46lm1LwKgh5/hr2ogUAaWMLvmL+VQrxXEClqp9BaFJIr3qNxgk0W6qqugT2FBVnpkN9T82863MSXRa5xuFsvUaa59ZAzXau0=";
//dinpay加密后字符串
string BEncyptData = "Ngmux6aW0w/0Lbb2WCRNytMPPuDnBxJtCGX55vwJpbGxjhWcYr932nZHIxYPpV+dkXkiJ0dBvBwbLkiAzsMa1L2hQw7RyjavAtkFmWFnHdjASVYvVhyhau/IFlYVHu65tAzO12ylrvmsWdNS0ysU/fheDcakoZAfmPRT6zqshqc=";
writeStr += ("<p>test sign and encrypt</p>");

//密钥转换为C#专用密钥
 APriKey = RSAPrivateKeyJava2DotNet(APriKey);
 BPubKey = RSAPublicKeyJava2DotNet(BPubKey);

 //加密、解密、签名、验签
 string encyptData = RSAEncrypt(plainText,BPubKey);
 writeStr += ("<p>merchant encrypted data:"+encyptData+"</p>");
 string signData = RSASign(plainText,APriKey);
 writeStr += ("<p>merchant signed data:"+signData+"</p>");
 bool validateResult = ValidateRsaSign(plainText,BPubKey,BSignedData);
 writeStr += ("<p>merchant validate sign result:"+validateResult+"</p>");
 string decryptData = RSADecrypt(BEncyptData,APriKey);
 writeStr += ("<p>merchant decrypted data:"+decryptData+"</p>");
}

///利用B公钥加密
public static string RSAEncrypt(string plainText,string publicKey)
{
    try{
            byte[] dataBytes = UTF8Encoding.UTF8.GetBytes(plainText);
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            RSAParameters para = new RSAParameters();
            rsa.FromXmlString(publicKey);
            return Convert.ToBase64String(rsa.Encrypt(dataBytes,false));
        }catch(Exception e){
            throw e;
        }
}

///利用A私钥签名
public static string RSASign(string plainText,string privateKey){
    try{
        RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
        RSAParameters para = new RSAParameters();
        rsa.FromXmlString(privateKey);
        byte[] signBytes = rsa.SignData(UTF8Encoding.UTF8.GetBytes(plainText),"md5");
        return Convert.ToBase64String(signBytes);
    }catch(Exception e){
        throw e;
    }
}

///利用B公钥验签
public static bool ValidateRsaSign(string plainText,string publicKey,string signedData){
    try{
        RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
        RSAParameters para = new RSAParameters();
        rsa.FromXmlString(publicKey);
        return rsa.VerifyData(UTF8Encoding.UTF8.GetBytes(plainText),"md5",Convert.FromBase64String(signedData));
       } catch(Exception e){
        throw e;
    }
}

///利用A私钥进行解密
public static string RSADecrypt(string encyptData,string privateKey) {
    try{
        byte[] encryptedBytes =  Convert.FromBase64String(encyptData);
        RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
        RSAParameters para = new RSAParameters();
        rsa.FromXmlString(privateKey);
        return UTF8Encoding.UTF8.GetString (rsa.Decrypt(encryptedBytes,false));
    } catch(Exception e){
         throw;
    }
}
    /// <summary>
    /// RSA私钥格式转换,java->.net
    /// </summary>
    /// <param name="privateKey">java生成的RSA私钥</param>
    /// <returns></returns>
    public static string RSAPrivateKeyJava2DotNet(string privateKey)
    {
        RsaPrivateCrtKeyParameters privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKey));
 
        return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent><P>{2}</P><Q>{3}</Q><DP>{4}</DP><DQ>{5}</DQ><InverseQ>{6}</InverseQ><D>{7}</D></RSAKeyValue>",
            Convert.ToBase64String(privateKeyParam.Modulus.ToByteArrayUnsigned()),
            Convert.ToBase64String(privateKeyParam.PublicExponent.ToByteArrayUnsigned()),
            Convert.ToBase64String(privateKeyParam.P.ToByteArrayUnsigned()),
            Convert.ToBase64String(privateKeyParam.Q.ToByteArrayUnsigned()),
            Convert.ToBase64String(privateKeyParam.DP.ToByteArrayUnsigned()),
            Convert.ToBase64String(privateKeyParam.DQ.ToByteArrayUnsigned()),
            Convert.ToBase64String(privateKeyParam.QInv.ToByteArrayUnsigned()),
            Convert.ToBase64String(privateKeyParam.Exponent.ToByteArrayUnsigned()));
    }
    /// <summary>
    /// RSA公钥格式转换,java->.net
    /// </summary>
    /// <param name="publicKey">java生成的公钥</param>
    /// <returns></returns>
    public static string RSAPublicKeyJava2DotNet(string publicKey)
    {
        RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey));
        return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent></RSAKeyValue>",
            Convert.ToBase64String(publicKeyParam.Modulus.ToByteArrayUnsigned()),
            Convert.ToBase64String(publicKeyParam.Exponent.ToByteArrayUnsigned()));
    }
</script>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta charset="UTF-8">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <%=writeStr%>
    </form>
</body>
</html>



php代码(rsa.php)

<?php
header("Content-type: text/html; charset=utf-8"); 
$private_key = '-----BEGIN RSA PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJ/GDO8pmSH9y+u4
WJgD5HbWqeneohmDQ8D4opJSaEoKcZzaiM+VrJdK4w+LjTgWeCLdqIl+5Ju28vo4
qvIn3/STyFn0G50Ru65kjzf3b/3nVmexttI95+I1fWeZ6F+vYbg2yVMSne6TvLj7
I+sZx2gmQYNm3w1DGFt1CTjWZ7TRAgMBAAECgYAIOlvKKTtAm+BXiEvPsEugrxda
+uMgKzlfA67jmCjUv0rwh/SJtCyKMgoVb9ta6xVOvlmCky1Us4w5xJdRFyqaSfli
pbEvz3E1N0abID5mgNOulvU2jn4v91DqFfiMOOAA+iGe9VdlWF96fmVLJuqd4MXf
NpTQP7KZ3iCUxpizkQJBAMs9N1LmkVlizXnY7JXS0l8hycr4UinvxPc8ZzM/Mhs8
pMyYHWWmN3p4YgrZLou2r1QYhCuUMbLwHPMKjging4UCQQDJQDjsndW94gtu3AnH
5e5g0worVETIvlstC2tvynZdSWuLXrbHQuh+6/t4ibpW3NrZTybKuersGd2Djbss
mu/dAkEAkvgRqcFSGnF4ZUSY0T9DIcgtRLmNsQXSSXdEqappcYjJI6pcl8U7GTU0
sOOc5SuWXhnceicQSXWZeaeITnnUgQJAPKt0vbhTUFwN0EzbUfz6IQxeG3PbDJ1+
RRUVPW1Ow463shtKhMWh62letRboKvmHrE1VR3ZG4QhnJBqdG7RVrQJAeLBjIDFd
LsfqakL7vpM/3kozQLeYgC6sqUJ2fxPjkReg4Re1POVdg19XrAXbPBUzlks7QFyF
DaodKUBjI28HLQ==
-----END RSA PRIVATE KEY-----';
 
$public_key = '-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCfxgzvKZkh/cvruFiYA+R21qnp
3qIZg0PA+KKSUmhKCnGc2ojPlayXSuMPi404Fngi3aiJfuSbtvL6OKryJ9/0k8hZ
9BudEbuuZI8392/951ZnsbbSPefiNX1nmehfr2G4NslTEp3uk7y4+yPrGcdoJkGD
Zt8NQxhbdQk41me00QIDAQAB
-----END PUBLIC KEY-----';
 
//echo $private_key;
$pi_key = openssl_pkey_get_private($private_key);//这个函数可用来判断私钥是否是可用的,可用返回资源id Resource id
$pu_key = openssl_pkey_get_public($public_key);//这个函数可用来判断公钥是否是可用的
 
 
$data = "01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789";//原始数据(有长度限制)
echo 'plainText: ',$data,'<br>';
openssl_public_encrypt($data,$encrypted,$pu_key);//公钥加密
$encrypted = base64_encode($encrypted);
echo "public key encrypt: ",$encrypted,"<br/>";

openssl_private_decrypt(base64_decode($encrypted),$decrypted,$pi_key);//私钥解密
echo "private key decrypted: ",$decrypted;

echo "</br>";
$plainText = "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789";//无长度限制
if (openssl_sign($plainText, $out, $pi_key,OPENSSL_ALGO_MD5))
{
    echo base64_encode($out);
}
$sig = $out;
echo "<br>";
if (openssl_verify($plainText, $sig, $pu_key,OPENSSL_ALGO_MD5) === 1)
{
    echo "validate sign ok";
}else{
    echo "validate sign faile";
}
?>




转载于:https://my.oschina.net/u/1164681/blog/544222

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值