文档章节

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

jason-寒江雪
 jason-寒江雪
发布于 2015/12/14 19:02
字数 2358
阅读 1076
收藏 20

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

最近公司项目需要用到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";
}
?>




© 著作权归作者所有

jason-寒江雪
粉丝 6
博文 6
码字总数 9514
作品 0
深圳
架构师
私信 提问
加载中

评论(1)

Ronnie_90
Ronnie_90
对base64的jar包是不是有要求啊?请问用那一个jar包
微软为什么要根据java,推出C#呢?

java即能写客户端,又能写服务端,网站,手机程序,那么同是java写的程序,网站和普通客户端能更好的配合吗? 比如PHP写的网站,和C++配合起来,就不如java写的网站,配合JAVA写的客户端? ...

Pwarn
2015/04/05
1K
16
Java服务端与C#客户端实现websocket通信(发送消息和文件)

设计思路 使用websocket通信,客户端采用C#开发界面,服务端使用Java开发,最终实现Java服务端向C#客户端发送消息和文件,C#客户端实现语音广播的功能。 Java服务端设计 Java端发送请求指令 ...

青衣霓裳
2018/11/01
1K
0
基于Thrift的java和PHP互相调用范例

首先我们看看 Thrift是什么? thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发。它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java, Go,Python, PHP, Ruby, Erlang,...

r00txx
2016/09/09
743
0
分享一个简单易用的RPC开源项目—Tatala

这个项目最早(2008年)是用于一个网络游戏的Cache Server,以及一个电子商务的Web Session服务。后来不断增加新的功能,除了Java还支持C#,到现在已经可以用它来开发网络游戏的服务器。等过些...

zijan
2014/04/08
201
1
Thrift 学习笔记1——Ubuntu环境下Thrift的安装、编译以及测试

1、Thrift 概念 Thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发。它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell,...

天外飞鱼
2013/06/08
785
0

没有更多内容

加载失败,请刷新页面

加载更多

JS其他类型值转化为Boolean类型规则

本文转载于:专业的前端网站➤JS其他类型值转化为Boolean类型规则 由于最近在笔试的时候,发现好多关于其他类型转化为Boolean类型的题目,因此总结一下! 一、String类型转化为Boolean 1.转化...

前端老手
37分钟前
4
0
EurekaClient自动装配及启动流程解析

在上篇文章中,我们简单介绍了EurekaServer自动装配及启动流程解析,本篇文章则继续研究EurekaClient的相关代码 老规矩,先看spring.factories文件,其中引入了一个配置类EurekaDiscoveryClie...

Java学习录
43分钟前
8
0
析构函数是否必须为虚函数?为何?

p517 在C++中,基类指针可以指向一个派生类的对象。如果基类的析构函数不是虚函数,当需要delete这个指向派生类的基类指针时,就只会调用基类的析构函数,而派生类的析构函数无法被调用。容易...

天王盖地虎626
44分钟前
5
0
【TencentOS tiny】深度源码分析(7)——事件

引言 大家在裸机编程中很可能经常用到flag这种变量,用来标志一下某个事件的发生,然后在循环中判断这些标志是否发生,如果是等待多个事件的话,还可能会if((xxx_flag)&&(xxx_flag))这样子做...

杰杰1号
47分钟前
9
0
聊聊nacos client的ServerHttpAgent

序 本文主要研究一下nacos client的ServerHttpAgent HttpAgent nacos-1.1.3/client/src/main/java/com/alibaba/nacos/client/config/http/HttpAgent.java public interface HttpAgent { ......

go4it
53分钟前
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部