之前发了一篇"TripleDes的加解密Java、C#、php通用代码",后面又有项目用到了Rsa加解密,还是在不同系统之间进行交互,Rsa在不同语言的密钥格式不一样,所以过程中主要还是密钥转换问题,为方便密钥转换,写了一个XML和PEM格式的密钥转换工具,文章后面会提供密钥转换工具的下载地址,通过搜索参考和研究终于搞定了在Java、C#和Php都可以通用的加解密代码,整理了Rsa的加解密代码做个记录,以后可以参考,大家应该都知道Rsa算法,这里就不说明了,直接看代码(代码主要是公钥加密私钥解密,密文统一进行base64编码,密钥长度为2048):

Java版本:

package com.jaamy.common.util;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.Key;
import java.security.KeyFactory;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec; import javax.crypto.Cipher; import org.apache.commons.codec.binary.Base64; public class RSACryptoUtil { /**
* 加密算法RSA
*/
public static final String KEY_ALGORITHM = "RSA";
/**
* 填充方式
*/
public static final String CIPHER_TRANSFORMAT = "RSA/ECB/PKCS1Padding"; /**
* RSA最大加密明文大小
*/
private static final int MAX_ENCRYPT_BLOCK = 245; /**
* RSA最大解密密文大小
*/
private static final int MAX_DECRYPT_BLOCK = 256; /**
* 公钥加密
* @param content 原文
* @param publicKey 公钥
* @param inputCharset 字符编码
* @return 加密后的字符串(base64)
* @throws Exception
*/
public static String encryptByPublicKey(String content, String publicKey, String inputCharset)
throws Exception { byte[] data = content.getBytes(inputCharset);
byte[] keyBytes = Base64.decodeBase64(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicK = keyFactory.generatePublic(x509KeySpec); // 对数据加密
Cipher cipher = Cipher.getInstance(CIPHER_TRANSFORMAT);
cipher.init(Cipher.ENCRYPT_MODE, publicK);
int inputLen = data.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(data, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
out.close(); return Base64.encodeBase64String(encryptedData);
} /**
* 私钥解密
* @param content 密文(base64)
* @param privateKey 私钥
* @param inputCharset 字符编码
* @return
* @throws Exception
*/
public static String decryptByPrivateKey(String content,
String privateKey, String inputCharset) throws Exception { byte[] encryptedData = Base64.decodeBase64(content);
byte[] keyBytes = Base64.decodeBase64(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec); Cipher cipher = Cipher.getInstance(CIPHER_TRANSFORMAT);
cipher.init(Cipher.DECRYPT_MODE, privateK);
int inputLen = encryptedData.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(encryptedData, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher
.doFinal(encryptedData, 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, inputCharset);
} /**
* 从文件中加载密钥字符串
* @return 是否成功
* @throws Exception
*/
public static String loadKeyString(String keyFile){
String keyString="";
InputStream in=null;
BufferedReader br=null;
try {
in=RSACryptoUtil.class.getResourceAsStream("/"+keyFile);
br= new BufferedReader(new InputStreamReader(in));
String readLine= null;
StringBuilder sb= new StringBuilder();
while((readLine= br.readLine())!=null){
if(readLine.charAt(0)=='-'){
continue;
}else{
sb.append(readLine);
sb.append('\r');
}
}
keyString=sb.toString();
} catch (IOException e) {
} catch (Exception e) { }finally{
if(br!=null){
try {
br.close();
} catch (IOException e) {
}
}
if(in!=null){
try {
in.close();
} catch (IOException e) {
}
}
}
return keyString;
} /**
* 从文件中加载密钥字符串 根据文件路径加载
* @return 是否成功
* @throws Exception
*/
public static String loadKeyStringByPath(String keyFile){
String keyString="";
InputStream in=null;
BufferedReader br=null;
try {
in = new FileInputStream(keyFile);
br= new BufferedReader(new InputStreamReader(in));
String readLine= null;
StringBuilder sb= new StringBuilder();
while((readLine= br.readLine())!=null){
if(readLine.charAt(0)=='-'){
continue;
}else{
sb.append(readLine);
sb.append('\r');
}
}
keyString=sb.toString();
} catch (IOException e) {
System.out.println(e.getMessage());
} catch (Exception e) {
System.out.println(e.getMessage()); }finally{
if(br!=null){
try {
br.close();
} catch (IOException e) {
}
}
if(in!=null){
try {
in.close();
} catch (IOException e) {
}
}
}
return keyString;
} public static void main(String[] args) throws Exception {
String publicKey = RSAUtils.loadKeyStringByPath("D:/sso_public_key_test.pem");
System.out.println(RSACryptoUtil.encryptByPublicKey("123", publicKey, "utf-8"));
}
}

C#版本:

/// <summary>
/// RSA加密+base64
/// </summary>
/// <param name="publickey">公钥</param>
/// <param name="content">原文</param>
/// <returns>加密后的密文字符串</returns>
public static string RSAEncrypt(string publickey, string content)
{
//最大文件加密块
int MAX_ENCRYPT_BLOCK = ; RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
byte[] cipherbytes;
rsa.FromXmlString(publickey);
byte[] contentByte = Encoding.UTF8.GetBytes(content);
int inputLen = contentByte.Length; int offSet = ;
byte[] cache;
int i = ;
System.IO.MemoryStream aMS = new System.IO.MemoryStream();
// 对数据分段加密
while (inputLen - offSet > )
{
byte[] temp = new byte[MAX_ENCRYPT_BLOCK];
if (inputLen - offSet > MAX_ENCRYPT_BLOCK)
{
Array.Copy(contentByte, offSet, temp, , MAX_ENCRYPT_BLOCK);
cache = rsa.Encrypt(Encoding.UTF8.GetBytes(content), false);
}
else
{
Array.Copy(contentByte, offSet, temp, , inputLen - offSet);
cache = rsa.Encrypt(Encoding.UTF8.GetBytes(content), false);
}
aMS.Write(cache, , cache.Length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
} cipherbytes = aMS.ToArray();
return Convert.ToBase64String(cipherbytes);
} /// <summary>
/// RSA解密
/// </summary>
/// <param name="privatekey">私钥</param>
/// <param name="content">密文(RSA+base64)</param>
/// <returns>解密后的字符串</returns>
public static string RSADecrypt(string privatekey, string content)
{
//最大文件解密块
int MAX_DECRYPT_BLOCK = ; RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
byte[] cipherbytes;
rsa.FromXmlString(privatekey);
byte[] contentByte = Convert.FromBase64String(content);
int inputLen = contentByte.Length; // 对数据分段解密
int offSet = ;
int i = ;
byte[] cache;
System.IO.MemoryStream aMS = new System.IO.MemoryStream();
while (inputLen - offSet > )
{
byte[] temp = new byte[MAX_DECRYPT_BLOCK];
if (inputLen - offSet > MAX_DECRYPT_BLOCK)
{
Array.Copy(contentByte, offSet, temp, , MAX_DECRYPT_BLOCK);
cache = rsa.Decrypt(temp, false);
}
else
{
Array.Copy(contentByte, offSet, temp, , inputLen - offSet);
cache = rsa.Decrypt(temp, false);
}
aMS.Write(cache, , cache.Length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
cipherbytes = aMS.ToArray(); return Encoding.UTF8.GetString(cipherbytes);
}

Php版本:

<?php
#私钥
$private_key = '-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCocmvQIWD2L9TW
N1uKpLONwHcdy2oaKoW1CtI8PB+S+UjdEuLl3usWEuh3ZgLYloPyD9553SJFn7an
fOplHITBqASOIXt9pi0CkahUPgwCPj4Dke5cT3fsp2i243/FX3afzrcf7FfTrEv/
LT22wF3csqrGt/UhqMcmpWIpPaL8edoCwGRBhghzEWaRwPZ2x5RPg+9qTSy0M7QG
u+8EwYDnNkGGuuIwzNxklclic9Unp96eVp33vOP/LNvz90OcuqGQQcABh+e2ttv6
VzqlRcD1GRhxqkT3erXmgbQAVm6JQHArK1Up10No+lth1tri5TGcL0BEF7PetDIj
jYh+aCLpAgMBAAECggEAPjFI1yaLyzmrxo/Xz5+x36NxF2IUQabziP1+09iK+9Po
cB9aAO9GMvc2N2dFo7wm6Uesp6fa0IQAh2RakoxuA6ZKUEPSeXjSY4Ft+fSSsH1U
njLSI+j/aTQCOIxUj4YIoUZMXJABeVjDEmscvw3VWffpj8c5zXyoUv9696kXNUoa
uHOuphe1UNc3ghFIpWK+7ScxkPB6KtmAFwD4LSbT9OwhPozavBqouQvhLt1bXO8C
ycKq4f1Pzhtt3sq3BRsPwqGhWt1NK95upKQuDnk1kJHjNzScH1FZxhsBHLxwOJ6E
M7HP5Ywh78umusaNPVLMM6+YVWbENg+WZZcXd/XspQKBgQDRIhIukY7m7fRBH0CP
mHi20gUmn7HzXgLxlbcU5n2PMDHHOg8D+Nmz1MnYPRQNwqxJdH8HOk8YQDC2uA+h
BpyCpvPbp6y6SnZw8bhqiNfSHBjEftmg7lUU5xzBiBo6SyCyLkWD2xa/O8Vyh6ut
/G1mQpNNJWWt5b+g5c4i0/fIhwKBgQDOMjGcLS8zHnZ30ZsWUS39iZ5TZXPCldTl
Q9JB5PnB4CajYmQEdw3n9C6mOO42b+3M04mmqo1r0HiNyA9lZQQNsM3KqG+ngGvE
0DM1cAyuz3Fi3XTIhAbRyXXyVbqBp5Yh2/O2lvrsInusJrimDRgwglquu2GsdVrj
+++b2DFFDwKBgQCkfXLlk/FdK44xZn5mM1vHGBubDIJv0+Lm14Yf90aMyDBu7fh/
fEznSBfWb/wE8riGMg3zxmYNwfdO0Cji04torB4kB5cxE35jSYxupuFxzk2gx9Eu
5iafgUQ56G4QqaS24PQmSL10fnPHqHRdLa1ygCzRwfdettVpnTbsZ+J9owKBgQDF
o2Tb3o9sPxmsdVNiy8L6TstcAlU3wOfELQK+uFwQ0eoXFvrpMLg6iVmhZ9YkhZp4
hpZdEwLkwXib5ZOkS3PcL4jBZDtJYRVrG2jKIrF1aU60RbJnc+0ZbjHIaxWOqvSD
VdE/RW4TomXKN38rYke6T2feLatMY1wQRG6BgXKQTwKBgQDKfK9Xuqzx+WI4AohT
EwKrQEZUMD+6DTESHHG9As4zMJ9zU+6iPpM4Gw4CzfJZHhPP4dD+TC9NcvvR+GC9
UkwxmZrvP1+6KNFp0DZNk6M9wPZuYM/E63Vy0sFEA+/gFp4vQh8k7N8n/n7DhR3v
kLuPdicfsKcz0thxzyDjv6oR2g==
-----END PRIVATE KEY-----'; #公钥
$public_key = '-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqHJr0CFg9i/U1jdbiqSz
jcB3HctqGiqFtQrSPDwfkvlI3RLi5d7rFhLod2YC2JaD8g/eed0iRZ+2p3zqZRyE
wagEjiF7faYtApGoVD4MAj4+A5HuXE937KdotuN/xV92n863H+xX06xL/y09tsBd
3LKqxrf1IajHJqViKT2i/HnaAsBkQYYIcxFmkcD2dseUT4Pvak0stDO0BrvvBMGA
5zZBhrriMMzcZJXJYnPVJ6fenlad97zj/yzb8/dDnLqhkEHAAYfntrbb+lc6pUXA
9RkYcapE93q15oG0AFZuiUBwKytVKddDaPpbYdba4uUxnC9ARBez3rQyI42Ifmgi
6QIDAQAB
-----END PUBLIC KEY-----'; $pi_key = openssl_pkey_get_private($private_key);
$pu_key = openssl_pkey_get_public($public_key); #公钥加密数据 rsa+base64
$data = "hello world!";
openssl_public_encrypt($data,$encrypted,$pu_key);
$base64_encrypted = base64_encode($encrypted);
echo $base64_encrypted."\n"; #私钥解密数据
openssl_private_decrypt(base64_decode($base64_encrypted),$decrypted_data,$pi_key); echo $decrypted_data; ?>

Rsa加解密C#和Java、php使用的密钥格式不一样,这里提供一个密钥转换工具:Rsa密钥转换工具v2.0.zip

Rsa加解密Java、C#、php通用代码 密钥转换工具的更多相关文章

  1. PHP RSA加解密详解(附代码)

    前言:RSA加密一般用在涉及到重要数据时所使用的加密算法,比如用户的账户密码传输,订单的相关数据传输等. 加密方式说明:公钥加密,私钥解密.也可以  私钥加密,公钥解密 一.RSA简介 RSA公钥加密 ...

  2. 前后端java+vue 实现rsa 加解密与摘要签名算法

    RSA 加密.解密.签名.验签.摘要,前后端java+vue联调测试通过 直接上代码 // 注意:加密密文与签名都是唯一的,不会变化.// 注意:vue 端密钥都要带pem格式.java 不要带pem ...

  3. 与非java语言使用RSA加解密遇到的问题:algid parse error, not a sequence

    遇到的问题 在一个与Ruby语言对接的项目中,决定使用RSA算法来作为数据传输的加密与签名算法.但是,在使用Ruby生成后给我的私钥时,却发生了异常:IOException: algid parse ...

  4. 全面解决.Net与Java互通时的RSA加解密问题,使用PEM格式的密钥文件

    作者: zyl910 一.缘由 RSA是一种常用的非对称加密算法.所以有时需要在不用编程语言中分别使用RSA的加密.解密.例如用Java做后台服务端,用C#开发桌面的客户端软件时. 由于 .Net.J ...

  5. 自己实现简单的RSA秘钥生成与加解密(Java )

    最近在学习PKI,顺便接触了一些加密算法.对RSA着重研究了一下,自己也写了一个简单的实现RSA算法的Demo,包括公.私钥生成,加解密的实现.虽然比较简单,但是也大概囊括了RSA加解密的核心思想与流 ...

  6. 【转】 Java 进行 RSA 加解密时不得不考虑到的那些事儿

    [转] Java 进行 RSA 加解密时不得不考虑到的那些事儿 1. 加密的系统不要具备解密的功能,否则 RSA 可能不太合适 公钥加密,私钥解密.加密的系统和解密的系统分开部署,加密的系统不应该同时 ...

  7. java RSA加解密以及用途

    在公司当前版本的中间件通信框架中,为了防止非授权第三方和到期客户端的连接,我们通过AES和RSA两种方式的加解密策略进行认证.对于非对称RSA加解密,因为其性能耗费较大,一般仅用于认证连接,不会用于每 ...

  8. RSA加解密工具类RSAUtils.java,实现公钥加密私钥解密和私钥解密公钥解密

    package com.geostar.gfstack.cas.util; import org.apache.commons.codec.binary.Base64; import javax.cr ...

  9. RSA加解密用途简介及java示例

    在公司当前版本的中间件通信框架中,为了防止非授权第三方和到期客户端的连接,我们通过AES和RSA两种方式的加解密策略进行认证.对于非对称RSA加解密,因为其性能耗费较大,一般仅用于认证连接,不会用于每 ...

随机推荐

  1. 【转】nginx中的ngx_cdecl

    http://blog.csdn.net/midion9/article/details/50605337 看nginx的代码时,发现有些函数返回值之后,还有一个ngx_cdecl关键字,如:   1 ...

  2. 自动化运维:flask-bootstrap + highstock整合

    1.在flask-bootstrap的base.html模板中加载highstock.js      以下是base.html的源码中,调用js文件的例子. 文件路径:python2.7/site-p ...

  3. handshake_failure

    在java 1.6版本中,通过HttpsURLConnection请求class 1(多发生于免费ssl证书,比如沃通或者startssl的)的https网络地址时,可能会报握手异常: Caused ...

  4. FastDFS----recovery状态问题排查记录

     FastDFS问题排查记录现象今天有人反馈,客户端部分图标时而不能显示问题定位用jemter将图片地址进行简单测试后,发现偶尔有404 NOT FOUND的情况在服务器上对八台nginx分别进行测试 ...

  5. 加密配置文件(App.Config和Web.config)中connectionStrings通用方法

    1. 背景:根据项目的要求,需要对配置文件配置的数据库连接字符串进行加密,也就是对ConnectinString节点的内容进行加密存储,同时考虑到代码使用连接字符串不需要进行更改,C#会自动对加密的内 ...

  6. vim中执行shell命令

    1):!command   不退出vim,并执行shell命令command,将命令输出显示在vim的命令区域,不会改变当前编辑的文件的内容   例如   :!ls -l   特别的可以运行:!bas ...

  7. How to backup your blogs on cnblogs

    This is an alternative to OfflineExplorer. Thanks for this article[1] which is listed in Reference s ...

  8. HTML input-file 上传类型控制

    HTML input-file 上传类型控制 input file 属性 accept 表示可以选择的文件MIME类型,多个MIME类型用英文逗号分开,常用的MIME类型见下表. 只能选择png和gi ...

  9. 数据挖掘之KNN算法(C#实现)

    在十大经典数据挖掘算法中,KNN算法算得上是最为简单的一种.该算法是一种惰性学习法(lazy learner),与决策树.朴素贝叶斯这些急切学习法(eager learner)有所区别.惰性学习法仅仅 ...

  10. XPath Checker和Firebug安装与使用

    一.XPath Checker和Firebug简介 XPath Checker和Firebug是写爬虫过程中提取数据的非常有用的插件工具,直接打开火狐浏览器的菜单就可以下载 二.XPath Check ...