-
依赖说明
commons-cli
用于格式化命令行参数 -
编译说明 采用
JDK7
编译,导出为runnable jar file -
使用手册
java -jar RSATools.jar
查看帮助java -jar RSATools.jar -g -length 2048
生成一个长度为2048位的密钥对。length参数可以忽略,默认为1024java -jar RSATools.jar -g -lang c#
生成一个长度为1024位的密钥对,格式为c#语言下的格式java -jar RSATools.jar -g -public rsa_public_key.pem -private rsa_private_key_pkcs8.pem
生成一个长度为1024位的密钥对,公钥文件名为rsa_public_key.pem;私钥文件名为rsa_private_key_pkcs8.pemjava -jar RSATools.jar -c -lang c# -public public.xml -private private.xml
将一个c#格式的密钥对文件转换为openssl方式下的格式密钥对,c#格式的公钥文件为public.xml,私钥文件为private.xmljava -jar RSATools.jar -c -public rsa_public_key.pem -private rsa_private_key_pkcs8.pem
将openssl格式的密钥对转换为c#使用的密钥对java -jar RSATools.jar -encode srctxt -public rsa_public_key.pem
使用rsa_public_key.pem加密字符串srctxt
,得到一个加密后的Base64字符串java -jar RSATools.jar -decode encodetxt -public rsa_private_key_pkcs8.pem
使用rsa_private_key_pkcs8.pem解密字符串encodetxt
,得到原文
Last active
August 29, 2015 14:26
-
-
Save borgle/c2477d76dfb13e31176d to your computer and use it in GitHub Desktop.
RSA工具:可以生成密钥对,可以把c#格式、openssl格式的密钥对进行互转,可以进行字符串的加解密。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.gkeeps.tools; | |
import java.io.BufferedReader; | |
import java.io.FileInputStream; | |
import java.io.InputStream; | |
import java.io.InputStreamReader; | |
import java.nio.charset.Charset; | |
import java.security.interfaces.RSAPrivateCrtKey; | |
import java.security.interfaces.RSAPrivateKey; | |
import java.security.interfaces.RSAPublicKey; | |
import org.apache.commons.cli.CommandLine; | |
import org.apache.commons.cli.HelpFormatter; | |
import org.apache.commons.cli.Option; | |
import org.apache.commons.cli.Options; | |
import org.apache.commons.cli.ParseException; | |
import org.apache.commons.cli.PosixParser; | |
public class Application { | |
protected static CommandLine buildCommandline(String[] args) { | |
final Options options = new Options(); | |
// //////////////////////////////////////////////////// | |
Option opt = new Option("h", "help", false, "Print help"); | |
opt.setRequired(false); | |
options.addOption(opt); | |
opt = new Option("lang", "language", true, "the keyfile generated language. esage: c#, other"); | |
opt.setRequired(false); | |
options.addOption(opt); | |
opt = new Option("private", "privatekey", true, "private keyfile."); | |
opt.setRequired(false); | |
options.addOption(opt); | |
opt = new Option("public", "publickey", true, "public keyfile."); | |
opt.setRequired(false); | |
options.addOption(opt); | |
opt = new Option("g", "generate", false, "rsa keyfile generater."); | |
opt.setRequired(false); | |
options.addOption(opt); | |
opt = new Option("c", "convert", false, "covert keyfile to other language."); | |
opt.setRequired(false); | |
options.addOption(opt); | |
opt = new Option("length", "keylength", true, "set seckey length."); | |
opt.setRequired(false); | |
options.addOption(opt); | |
opt = new Option("encode", "encode", true, "encode something use public keyfile."); | |
opt.setRequired(false); | |
options.addOption(opt); | |
opt = new Option("decode", "decode", true, "decode something use private keyfile."); | |
opt.setRequired(false); | |
options.addOption(opt); | |
// //////////////////////////////////////////////////// | |
PosixParser parser = new PosixParser(); | |
HelpFormatter hf = new HelpFormatter(); | |
hf.setWidth(110); | |
CommandLine commandLine = null; | |
try { | |
commandLine = parser.parse(options, args); | |
if (commandLine.hasOption('h') || commandLine.getOptions().length == 0) { | |
hf.printHelp("RSAUtils", options, true); | |
return null; | |
} | |
} catch (ParseException e) { | |
hf.printHelp("RSAUtils", options, true); | |
return null; | |
} | |
return commandLine; | |
} | |
/** | |
* 获取密钥文件的内容 | |
* @param keyfile 密钥文件路径 | |
* @return String | |
*/ | |
protected static String getKeyString(String keyfile){ | |
String base64KeyString = ""; | |
try { | |
InputStream fis = new FileInputStream(keyfile); | |
InputStreamReader isr = new InputStreamReader(fis, Charset.forName("UTF-8")); | |
BufferedReader br = new BufferedReader(isr); | |
String line; | |
while ((line = br.readLine()) != null) { | |
if (line.startsWith("--")) | |
continue; | |
base64KeyString += line; | |
} | |
base64KeyString = base64KeyString.replace("\r", "").replace("\n", ""); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} | |
return base64KeyString; | |
} | |
public static void main(String[] args){ | |
CommandLine cmdline = buildCommandline(args); | |
if (cmdline == null) { | |
return; | |
} | |
String language = cmdline.getOptionValue("lang", "other").toLowerCase(); | |
String privateKeyfile = cmdline.getOptionValue("private", "rsa_private_key_pkcs8.pem"); | |
String publicKeyfile = cmdline.getOptionValue("public", "rsa_public_key.pem"); | |
String encodeString = cmdline.getOptionValue("encode"); | |
String decodeString = cmdline.getOptionValue("decode"); | |
Integer length = Integer.parseInt(cmdline.getOptionValue("length", "1024")); | |
Boolean isgenerater = cmdline.hasOption("g"); | |
Boolean isconvert = cmdline.hasOption("c"); | |
if (!language.equals("c#") && !language.equals("other")) { | |
System.out.println("the lanuage is wrong. esage: c#, other"); | |
return; | |
} | |
if(isgenerater){ | |
RSAUtils.GeneralKeyPair(length, language, privateKeyfile, publicKeyfile); | |
return; | |
} | |
if(isconvert){ | |
String privateKeyString = getKeyString(privateKeyfile); | |
String publicKeyString = getKeyString(publicKeyfile); | |
if(language.equals("c#")){ | |
//转换为openssl格式的密钥 | |
RSAPrivateKey privateKey = (RSAPrivateKey)RSAUtils.decodePrivateKeyFromXml(privateKeyString); | |
RSAPublicKey publicKey = (RSAPublicKey)RSAUtils.decodePublicKeyFromXml(publicKeyString); | |
RSAUtils.generatePrivateKeyFile(privateKey, "new_" + privateKeyfile); | |
RSAUtils.generatePublicKeyFile(publicKey, "new_" + publicKeyfile); | |
}else{ | |
//转换为c#格式的密钥 | |
RSAPrivateCrtKey privateKey = (RSAPrivateCrtKey)RSAUtils.decodePrivateKeyPKCS8(privateKeyString); | |
RSAPublicKey publicKey = (RSAPublicKey)RSAUtils.decodePublicKey(publicKeyString); | |
RSAUtils.generatePrivateKeyXmlFile(privateKey, "new_" + privateKeyfile); | |
RSAUtils.generatePublicKeyXmlFile(publicKey, "new_" + publicKeyfile); | |
} | |
return; | |
} | |
//加密 | |
if(encodeString !=null && encodeString.length()>0){ | |
String publicKeyString = getKeyString(publicKeyfile); | |
if(language.equals("c#")){ | |
RSAPublicKey publicKey = (RSAPublicKey)RSAUtils.decodePublicKeyFromXml(publicKeyString); | |
System.out.println("加密结果:\n" + RSAUtils.encrypt(publicKey, encodeString)); | |
}else{ | |
RSAPublicKey publicKey = (RSAPublicKey)RSAUtils.decodePublicKey(publicKeyString); | |
System.out.println("加密结果:\n" + RSAUtils.encrypt(publicKey, encodeString)); | |
} | |
return; | |
} | |
//解密 | |
if(decodeString !=null && decodeString.length()>0){ | |
String privateKeyString = getKeyString(privateKeyfile); | |
if(language.equals("c#")){ | |
RSAPrivateKey privateKey = (RSAPrivateKey)RSAUtils.decodePrivateKeyFromXml(privateKeyString); | |
System.out.println("解密结果:\n" + RSAUtils.decrypt(privateKey, decodeString)); | |
}else{ | |
RSAPrivateCrtKey privateKey = (RSAPrivateCrtKey)RSAUtils.decodePrivateKeyPKCS8(privateKeyString); | |
System.out.println("解密结果:\n" + RSAUtils.decrypt(privateKey, decodeString)); | |
} | |
return; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.gkeeps.tools; | |
import java.io.FileWriter; | |
import java.math.BigInteger; | |
import java.security.KeyFactory; | |
import java.security.KeyPair; | |
import java.security.KeyPairGenerator; | |
import java.security.PrivateKey; | |
import java.security.PublicKey; | |
import java.security.interfaces.RSAPrivateCrtKey; | |
import java.security.interfaces.RSAPrivateKey; | |
import java.security.interfaces.RSAPublicKey; | |
import java.security.spec.PKCS8EncodedKeySpec; | |
import java.security.spec.RSAPrivateCrtKeySpec; | |
import java.security.spec.RSAPublicKeySpec; | |
import java.security.spec.X509EncodedKeySpec; | |
import javax.crypto.Cipher; | |
import sun.misc.BASE64Decoder; | |
import sun.misc.BASE64Encoder; | |
import sun.reflect.generics.reflectiveObjects.NotImplementedException; | |
public class RSAUtils { | |
private static BASE64Encoder encoder = new BASE64Encoder(); | |
private static BASE64Decoder decoder = new BASE64Decoder(); | |
public static void GeneralKeyPair(Integer length, String language, String privateKeyfile, String publicKeyfile) { | |
try { | |
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA"); | |
// 初始化密钥对生成器,密钥大小为length位,单次加密字符串长度为length/8-11 | |
keyPairGen.initialize(length); | |
KeyPair keyPair = keyPairGen.generateKeyPair(); | |
if (language.equals("c#")) { | |
RSAPrivateCrtKey privateKey = (RSAPrivateCrtKey) keyPair.getPrivate(); | |
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); | |
generatePrivateKeyXmlFile(privateKey, privateKeyfile); | |
generatePublicKeyXmlFile(publicKey, publicKeyfile); | |
} else { | |
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); | |
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); | |
generatePrivateKeyFile(privateKey, privateKeyfile); | |
generatePublicKeyFile(publicKey, publicKeyfile); | |
} | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} | |
} | |
public static void generatePrivateKeyFile(RSAPrivateKey privateKey, String privateKeyfile) { | |
try { | |
FileWriter writer = new FileWriter(privateKeyfile); | |
writer.write("-----BEGIN RSA PRIVATE KEY-----\r\n"); | |
writer.write(encoder.encode(privateKey.getEncoded())); | |
writer.write("\r\n-----END RSA PRIVATE KEY-----"); | |
writer.flush(); | |
writer.close(); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} | |
} | |
public static void generatePublicKeyFile(RSAPublicKey publicKey, String publicKeyfile) { | |
try { | |
FileWriter writer = new FileWriter(publicKeyfile); | |
writer.write("-----BEGIN PUBLIC KEY-----\r\n"); | |
writer.write(encoder.encode(publicKey.getEncoded())); | |
writer.write("\r\n-----END PUBLIC KEY-----"); | |
writer.flush(); | |
writer.close(); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} | |
} | |
public static void generatePrivateKeyXmlFile(RSAPrivateCrtKey privateKey, String privateKeyfile) { | |
try { | |
FileWriter writer = new FileWriter(privateKeyfile); | |
writer.write("<?xml version=\"1.0\" encoding=\"gbk\" ?>\n"); | |
writer.write(encodePrivateKeyToXml(privateKey)); | |
writer.flush(); | |
writer.close(); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} | |
} | |
public static void generatePublicKeyXmlFile(RSAPublicKey publicKey, String publicKeyfile) { | |
try { | |
FileWriter writer = new FileWriter(publicKeyfile); | |
writer.write("<?xml version=\"1.0\" encoding=\"gbk\" ?>\n"); | |
writer.write(encodePublicKeyToXml(publicKey)); | |
writer.flush(); | |
writer.close(); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} | |
} | |
/** | |
* 采用公钥加密 | |
* @param publicKey 公钥对象 | |
* @param srcString 待加密字符串 | |
* @return 加密后的Base64字符串 | |
*/ | |
public static String encrypt(RSAPublicKey publicKey, String srcString) { | |
if (publicKey != null) { | |
try { | |
byte[] srcBytes = srcString.getBytes(); | |
// Cipher负责完成加密或解密工作,RSA/ECB/PKCS1Padding or PKCS8Padding | |
Cipher cipher = Cipher.getInstance("RSA"); | |
cipher.init(Cipher.ENCRYPT_MODE, publicKey); | |
byte[] resultBytes = cipher.doFinal(srcBytes); | |
return encoder.encode(resultBytes).replaceAll("\r|\n", ""); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} | |
} | |
return null; | |
} | |
/** | |
* 采用私钥解密 | |
* @param privateKey 私钥对象 | |
* @param encString 待解密的Base64字符串 | |
* @return 原始字符串 | |
*/ | |
public static String decrypt(RSAPrivateKey privateKey, String encString) { | |
if (privateKey != null) { | |
try { | |
byte[] encBytes = decoder.decodeBuffer(encString); | |
Cipher cipher = Cipher.getInstance("RSA"); | |
cipher.init(Cipher.DECRYPT_MODE, privateKey); | |
byte[] decBytes = cipher.doFinal(encBytes); | |
return new String(decBytes); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} | |
} | |
return null; | |
} | |
/** | |
* 从字符串中加载公钥 | |
*/ | |
public static PublicKey decodePublicKey(String publicKeyStr) { | |
try { | |
byte[] buffer = decoder.decodeBuffer(publicKeyStr); | |
KeyFactory keyFactory = KeyFactory.getInstance("RSA"); | |
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer); | |
return (RSAPublicKey) keyFactory.generatePublic(keySpec); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} | |
return null; | |
} | |
/** | |
* 从字符串中加载私钥PKCS8 | |
*/ | |
public static PrivateKey decodePrivateKeyPKCS8(String privateKeyStr) { | |
try { | |
byte[] buffer = decoder.decodeBuffer(privateKeyStr); | |
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer); | |
KeyFactory keyFactory = KeyFactory.getInstance("RSA"); | |
return (RSAPrivateKey) keyFactory.generatePrivate(keySpec); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} | |
return null; | |
} | |
/** | |
* 从字符串中加载私钥PKCS1 | |
*/ | |
public static PrivateKey decodePrivateKeyPKCS1(String privateKeyStr) { | |
// 依赖 org.bouncycastle | |
/* | |
* RSAPrivateKeyStructure asn1PrivKey = new | |
* RSAPrivateKeyStructure((ASN1Sequence) | |
* ASN1Sequence.fromByteArray(privateKeyStr)); RSAPrivateKeySpec | |
* rsaPrivKeySpec = new RSAPrivateKeySpec(asn1PrivKey.getModulus(), | |
* asn1PrivKey.getPrivateExponent()); KeyFactory keyFactory= | |
* KeyFactory.getInstance("RSA"); return | |
* keyFactory.generatePrivate(rsaPrivKeySpec); | |
*/ | |
throw new NotImplementedException(); | |
} | |
/** | |
* java公钥转换成C#公钥 | |
*/ | |
public static String encodePublicKeyToXml(RSAPublicKey publicKey) { | |
StringBuilder sb = new StringBuilder(); | |
sb.append("<RSAKeyValue>\n"); | |
sb.append("<Modulus>").append(encoder.encode(publicKey.getModulus().toByteArray()).replace("\r", "").replace("\n", "")) | |
.append("</Modulus>\n"); | |
sb.append("<Exponent>").append(encoder.encode(publicKey.getPublicExponent().toByteArray()).replace("\r", "").replace("\n", "")) | |
.append("</Exponent>\n"); | |
sb.append("</RSAKeyValue>"); | |
return sb.toString(); | |
} | |
/** | |
* C#公钥转换成java公钥 | |
*/ | |
public static PublicKey decodePublicKeyFromXml(String publicKeyXml) { | |
publicKeyXml = publicKeyXml.replaceAll("\r", "").replaceAll("\n", ""); | |
KeyFactory keyf; | |
try { | |
BigInteger modulus = new BigInteger(1, decoder.decodeBuffer( | |
publicKeyXml.substring(publicKeyXml.indexOf("<Modulus>") + 9, publicKeyXml.indexOf("</Modulus>")))); | |
BigInteger publicExponent = new BigInteger(1, decoder.decodeBuffer(publicKeyXml | |
.substring(publicKeyXml.indexOf("<Exponent>") + 10, publicKeyXml.indexOf("</Exponent>")))); | |
RSAPublicKeySpec rsaPubKey = new RSAPublicKeySpec(modulus, publicExponent); | |
keyf = KeyFactory.getInstance("RSA"); | |
return keyf.generatePublic(rsaPubKey); | |
} catch (Exception e) { | |
return null; | |
} | |
} | |
/** | |
* java私钥转换成C#私钥 | |
*/ | |
public static String encodePrivateKeyToXml(RSAPrivateCrtKey privateKey) { | |
StringBuilder sb = new StringBuilder(); | |
sb.append("<RSAKeyValue>\n"); | |
sb.append("<Modulus>").append(encoder.encode(privateKey.getModulus().toByteArray()).replace("\r", "").replace("\n", "")) | |
.append("</Modulus>\n"); | |
sb.append("<Exponent>").append(encoder.encode(privateKey.getPublicExponent().toByteArray()).replace("\r", "").replace("\n", "")) | |
.append("</Exponent>\n"); | |
sb.append("<P>").append(encoder.encode(privateKey.getPrimeP().toByteArray()).replace("\r", "").replace("\n", "")) | |
.append("</P>\n"); | |
sb.append("<Q>").append(encoder.encode(privateKey.getPrimeQ().toByteArray()).replace("\r", "").replace("\n", "")) | |
.append("</Q>\n"); | |
sb.append("<DP>").append(encoder.encode(privateKey.getPrimeExponentP().toByteArray()).replace("\r", "").replace("\n", "")) | |
.append("</DP>\n"); | |
sb.append("<DQ>").append(encoder.encode(privateKey.getPrimeExponentQ().toByteArray()).replace("\r", "").replace("\n", "")) | |
.append("</DQ>\n"); | |
sb.append("<InverseQ>").append(encoder.encode(privateKey.getCrtCoefficient().toByteArray()).replace("\r", "").replace("\n", "")) | |
.append("</InverseQ>\n"); | |
sb.append("<D>").append(encoder.encode(privateKey.getPrivateExponent().toByteArray()).replace("\r", "").replace("\n", "")) | |
.append("</D>\n"); | |
sb.append("</RSAKeyValue>"); | |
return sb.toString(); | |
} | |
/** | |
* C#私钥转换成java私钥 | |
*/ | |
public static PrivateKey decodePrivateKeyFromXml(String privateKeyXml) { | |
privateKeyXml = privateKeyXml.replaceAll("\r", "").replaceAll("\n", ""); | |
KeyFactory keyf; | |
try { | |
BigInteger modulus = new BigInteger(1, decoder.decodeBuffer(privateKeyXml | |
.substring(privateKeyXml.indexOf("<Modulus>") + 9, privateKeyXml.indexOf("</Modulus>")))); | |
BigInteger publicExponent = new BigInteger(1, decoder.decodeBuffer(privateKeyXml | |
.substring(privateKeyXml.indexOf("<Exponent>") + 10, privateKeyXml.indexOf("</Exponent>")))); | |
BigInteger privateExponent = new BigInteger(1, decoder.decodeBuffer( | |
privateKeyXml.substring(privateKeyXml.indexOf("<D>") + 3, privateKeyXml.indexOf("</D>")))); | |
BigInteger primeP = new BigInteger(1, decoder.decodeBuffer( | |
privateKeyXml.substring(privateKeyXml.indexOf("<P>") + 3, privateKeyXml.indexOf("</P>")))); | |
BigInteger primeQ = new BigInteger(1, decoder.decodeBuffer( | |
privateKeyXml.substring(privateKeyXml.indexOf("<Q>") + 3, privateKeyXml.indexOf("</Q>")))); | |
BigInteger primeExponentP = new BigInteger(1, decoder.decodeBuffer( | |
privateKeyXml.substring(privateKeyXml.indexOf("<DP>") + 4, privateKeyXml.indexOf("</DP>")))); | |
BigInteger primeExponentQ = new BigInteger(1, decoder.decodeBuffer( | |
privateKeyXml.substring(privateKeyXml.indexOf("<DQ>") + 4, privateKeyXml.indexOf("</DQ>")))); | |
BigInteger crtCoefficient = new BigInteger(1, decoder.decodeBuffer(privateKeyXml | |
.substring(privateKeyXml.indexOf("<InverseQ>") + 10, privateKeyXml.indexOf("</InverseQ>")))); | |
RSAPrivateCrtKeySpec rsaPriKey = new RSAPrivateCrtKeySpec(modulus, publicExponent, privateExponent, primeP, | |
primeQ, primeExponentP, primeExponentQ, crtCoefficient); | |
keyf = KeyFactory.getInstance("RSA"); | |
return keyf.generatePrivate(rsaPriKey); | |
} catch (Exception e) { | |
return null; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment