2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > [Linux] 使用openssl实现RSA非对称加密

[Linux] 使用openssl实现RSA非对称加密

时间:2022-07-01 16:19:53

相关推荐

[Linux] 使用openssl实现RSA非对称加密

简单定义:公钥和私钥,加密和解密使用的是两个不同的密钥,所以是非对称

系统:ubuntu 14.04

软件:openssl java php

生成公钥私钥

使用命令生成私钥:

openssl genrsa -out rsa_private_key.pem 1024

参数:genrsa 生成密钥 -out 输出到文件 rsa_private_key.pem 文件名 1024 长度

从私钥中提取公钥:

openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

参数: rsa 提取公钥 -in 从文件中读入 rsa_private_key.pem 文件名 -pubout 输出 -out 到文件 rsa_public_key.pem 文件名

shell加解密

新建一个readme.txt 内容是taoshihan

使用公钥加密:

openssl rsautl -encrypt -in readme.txt -inkey rsa_public_key.pem -pubin -out hello.en

参数: rsautl 加解密 -encrypt 加密 -in 从文件输入 readme.txt 文件名 -inkey 输入的密钥 rsa_public_key.pem 上一步生成的公钥 -pubin 表名输入是公钥文件 -out输出到文件 hello.en 输出文件名

使用私钥解密:

openssl rsautl -decrypt -in hello.en -inkey rsa_private_key.pem -out hello.de

参数: -decrypt 解密 -in 从文件输入 hello.en 上一步生成的加密文件 -inkey 输入的密钥 rsa_private_key.pem 上一步生成的私钥 -out输出到文件 hello.de 输出的文件名

cat hello.de // taoshihan

php加解密

$profile="taoshihan";echo "加密前:{$profile}\n";//公钥加密$public_key=file_get_contents("rsa_public_key.pem");$pub_key = openssl_pkey_get_public($public_key); openssl_public_encrypt($profile,$encrypted,$pub_key);$encrypted=base64_encode($encrypted);//因为加密后是乱码,所以base64一下echo "加密后:\n";echo $encrypted."\n";//私钥解密$private_key=file_get_contents("rsa_private_key.pem");$pi_key = openssl_pkey_get_private($private_key); openssl_private_decrypt(base64_decode($encrypted),$decrypted,$pi_key);echo "解密后:\n";echo $decrypted."\n";

新建rsa.php的文件

执行后结果:

加密前:taoshihan加密后:ShjsdlTceurVfO0ocENqHGl9RXrQRm3vuprqchhuVOdX1ldJC2O2sIvjjpQfPWOkF1WA+tqdyIl9YJQ0/2DqAp4zaqI1TCNsXduGn2iUZQ88g7B5eSI7r/iWKcX527pLe95EBvFMw/D65tlYscI5RClcp3KrOw2fqDQZ3D3nKAI=解密后:taoshihan

java加解密:

准备jar包 bcprov-ext-jdk15on-156.jar

wget /download/bcprov-ext-jdk15on-156.jar

RSAEncrypt.java 文件

import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.FileInputStream; import java.io.FileOutputStream;import java.security.InvalidKeyException;import java.security.KeyFactory;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.NoSuchAlgorithmException;import java.security.SecureRandom;import java.security.interfaces.RSAPrivateKey;import java.security.interfaces.RSAPublicKey;import java.security.spec.InvalidKeySpecException;import java.security.spec.PKCS8EncodedKeySpec;import java.security.spec.X509EncodedKeySpec;import java.security.KeyFactory;import java.security.interfaces.RSAPrivateKey;import java.security.spec.RSAPrivateKeySpec;import org.bouncycastle.asn1.ASN1Sequence;import org.bouncycastle.asn1.pkcs.RSAPrivateKeyStructure;import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.NoSuchPaddingException;import org.bouncycastle.jce.provider.BouncyCastleProvider;import sun.misc.BASE64Decoder;import sun.misc.BASE64Encoder;public class RSAEncrypt {/*** 私钥*/private RSAPrivateKey privateKey;/*** 公钥*/private RSAPublicKey publicKey;/*** 字节数据转字符串专用集合*/private static final char[] HEX_CHAR= {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};/*** 获取私钥* @return 当前的私钥对象*/public RSAPrivateKey getPrivateKey() {return privateKey;}/*** 获取公钥* @return 当前的公钥对象*/public RSAPublicKey getPublicKey() {return publicKey;}/*** 随机生成密钥对*/public void genKeyPair(){KeyPairGenerator keyPairGen= null;try {keyPairGen= KeyPairGenerator.getInstance("RSA");} catch (NoSuchAlgorithmException e) {e.printStackTrace();}keyPairGen.initialize(1024, new SecureRandom());KeyPair keyPair= keyPairGen.generateKeyPair();this.privateKey= (RSAPrivateKey) keyPair.getPrivate();this.publicKey= (RSAPublicKey) keyPair.getPublic();}/*** 从文件中输入流中加载公钥* @param in 公钥输入流* @throws Exception 加载公钥时产生的异常*/public void loadPublicKey(InputStream in) throws Exception{try {BufferedReader 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');}}loadPublicKey(sb.toString());} catch (IOException e) {throw new Exception("公钥数据流读取错误");} catch (NullPointerException e) {throw new Exception("公钥输入流为空");}}/*** 从字符串中加载公钥* @param publicKeyStr 公钥数据字符串* @throws Exception 加载公钥时产生的异常*/public void loadPublicKey(String publicKeyStr) throws Exception{try {BASE64Decoder base64Decoder= new BASE64Decoder();byte[] buffer= base64Decoder.decodeBuffer(publicKeyStr);KeyFactory keyFactory= KeyFactory.getInstance("RSA");X509EncodedKeySpec keySpec= new X509EncodedKeySpec(buffer);this.publicKey= (RSAPublicKey) keyFactory.generatePublic(keySpec);} catch (NoSuchAlgorithmException e) {throw new Exception("无此算法");} catch (InvalidKeySpecException e) {throw new Exception("公钥非法");} catch (IOException e) {throw new Exception("公钥数据内容读取错误");} catch (NullPointerException e) {throw new Exception("公钥数据为空");}}/*** 从文件中加载私钥* @param keyFileName 私钥文件名* @return 是否成功* @throws Exception */public void loadPrivateKey(InputStream in) throws Exception{try {BufferedReader 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');}}loadPrivateKey(sb.toString());} catch (IOException e) {throw new Exception("私钥数据读取错误");} catch (NullPointerException e) {throw new Exception("私钥输入流为空");}}public void loadPrivateKey(String privateKeyStr) throws Exception{try {BASE64Decoder base64Decoder= new BASE64Decoder();byte[] buffer= base64Decoder.decodeBuffer(privateKeyStr);RSAPrivateKeyStructure asn1PrivKey = new RSAPrivateKeyStructure((ASN1Sequence) ASN1Sequence.fromByteArray(buffer));RSAPrivateKeySpec rsaPrivKeySpec = new RSAPrivateKeySpec(asn1PrivKey.getModulus(), asn1PrivKey.getPrivateExponent());KeyFactory keyFactory= KeyFactory.getInstance("RSA");RSAPrivateKey priKey=(RSAPrivateKey) keyFactory.generatePrivate(rsaPrivKeySpec);this.privateKey=priKey;// PKCS8EncodedKeySpec keySpec= new PKCS8EncodedKeySpec(buffer);// KeyFactory keyFactory= KeyFactory.getInstance("RSA");//this.privateKey= (RSAPrivateKey) keyFactory.generatePrivate(keySpec);} catch (NoSuchAlgorithmException e) {throw new Exception("无此算法");} catch (InvalidKeySpecException e) {throw new Exception("私钥非法");} catch (IOException e) {throw new Exception("私钥数据内容读取错误");} catch (NullPointerException e) {throw new Exception("私钥数据为空");}}/*** 加密过程* @param publicKey 公钥* @param plainTextData 明文数据* @return* @throws Exception 加密过程中的异常信息*/public byte[] encrypt(RSAPublicKey publicKey, byte[] plainTextData) throws Exception{if(publicKey== null){throw new Exception("加密公钥为空, 请设置");}Cipher cipher= null;try {cipher= Cipher.getInstance("RSA/ECB/PKCS1Padding", new BouncyCastleProvider());cipher.init(Cipher.ENCRYPT_MODE, publicKey);byte[] output= cipher.doFinal(plainTextData);return output;} catch (NoSuchAlgorithmException e) {throw new Exception("无此加密算法");} catch (NoSuchPaddingException e) {e.printStackTrace();return null;}catch (InvalidKeyException e) {throw new Exception("加密公钥非法,请检查");} catch (IllegalBlockSizeException e) {throw new Exception("明文长度非法");} catch (BadPaddingException e) {throw new Exception("明文数据已损坏");}}/*** 解密过程* @param privateKey 私钥* @param cipherData 密文数据* @return 明文* @throws Exception 解密过程中的异常信息*/public byte[] decrypt(RSAPrivateKey privateKey, byte[] cipherData) throws Exception{if (privateKey== null){throw new Exception("解密私钥为空, 请设置");}Cipher cipher= null;try {cipher= Cipher.getInstance("RSA/ECB/PKCS1Padding", new BouncyCastleProvider());cipher.init(Cipher.DECRYPT_MODE, privateKey);byte[] output= cipher.doFinal(cipherData);return output;} catch (NoSuchAlgorithmException e) {throw new Exception("无此解密算法");} catch (NoSuchPaddingException e) {e.printStackTrace();return null;}catch (InvalidKeyException e) {throw new Exception("解密私钥非法,请检查");} catch (IllegalBlockSizeException e) {throw new Exception("密文长度非法");} catch (BadPaddingException e) {throw new Exception("密文数据已损坏");} }/*** 字节数据转十六进制字符串* @param data 输入数据* @return 十六进制内容*/public static String byteArrayToString(byte[] data){StringBuilder stringBuilder= new StringBuilder();for (int i=0; i<data.length; i++){//取出字节的高四位 作为索引得到相应的十六进制标识符 注意无符号右移stringBuilder.append(HEX_CHAR[(data[i] & 0xf0)>>> 4]);//取出字节的低四位 作为索引得到相应的十六进制标识符stringBuilder.append(HEX_CHAR[(data[i] & 0x0f)]);if (i<data.length-1){stringBuilder.append(' ');}}return stringBuilder.toString();}public static void main(String[] args){RSAEncrypt rsaEncrypt= new RSAEncrypt();//加载公钥try {rsaEncrypt.loadPublicKey(new FileInputStream("rsa_public_key.pem"));System.out.println("加载公钥成功");} catch (Exception e) {System.err.println(e.getMessage());System.err.println("加载公钥失败");}//加载私钥try {rsaEncrypt.loadPrivateKey(new FileInputStream("rsa_private_key.pem"));System.out.println("加载私钥成功");} catch (Exception e) {System.err.println(e.getMessage());System.err.println("加载私钥失败");}//测试字符串String encryptStr= "taoshihan";System.out.println("加密前:");System.out.println(encryptStr);try {//加密byte[] cipher = rsaEncrypt.encrypt(rsaEncrypt.getPublicKey(), encryptStr.getBytes());//解密byte[] plainText = rsaEncrypt.decrypt(rsaEncrypt.getPrivateKey(), cipher);BASE64Encoder encode = new BASE64Encoder(); String buffer= encode.encode(cipher);System.out.println("加密后:");System.out.println(new String(buffer));System.out.println("解密后:");System.out.println(new String(plainText));} catch (Exception e) {System.err.println(e.getMessage());}}}

带包编译和执行

javac -cp bcprov-ext-jdk15on-156.jar RSAEncrypt.java java -cp .:bcprov-ext-jdk15on-156.jar RSAEncrypt

执行结果:

加载公钥成功加载私钥成功加密前:taoshihan加密后:Tt1p5XnamZkkVjGn1cVgEIb7U+CP27Xw93JQQUZyc2Up/rJL4Mx+dA8mxkva1a/I64sUTb7QD//8gbss4bZY/DHrLityTt2/QjjQUFYD5/Aa1m1QKUBulWY4/C5so5dm6wrRnjolsIFUbY+RfH4B6hp1taQGBRDum/xEX6OsJ9I=解密后:taoshihan

shell使用公钥加密,php使用私钥解密

shell:

openssl rsautl -encrypt -in readme.txt -inkey rsa_public_key.pem -pubin|base64加密后的字符串lNJ50ODiofcp+adrtAI943HOsjdDTg3UMfUkt0NI7DhUjxCM+NAlBH08WVQRtYK9W8ZoQOta3QH6PzmJT4WsI0yfNGiUWYgoYgSOtPURSQMbaCt3DM2Y5mEKqzbKLrhN+S+9Jrtmef1VuBUes8wN6rODUHxI+vDwQ+utRJRRo9U=

php:

<?php$encrypted="lNJ50ODiofcp+adrtAI943HOsjdDTg3UMfUkt0NI7DhUjxCM+NAlBH08WVQRtYK9W8ZoQOta3QH6PzmJT4WsI0yfNGiUWYgoYgSOtPURSQMbaCt3DM2Y5mEKqzbKLrhN+S+9Jrtmef1VuBUes8wN6rODUHxI+vDwQ+utRJRRo9U=";echo $encrypted."\n";//私钥解密$private_key=file_get_contents("rsa_private_key.pem");$pi_key = openssl_pkey_get_private($private_key); openssl_private_decrypt(base64_decode($encrypted),$decrypted,$pi_key);echo "解密后:\n";echo $decrypted."\n";

执行结果:

lNJ50ODiofcp+adrtAI943HOsjdDTg3UMfUkt0NI7DhUjxCM+NAlBH08WVQRtYK9W8ZoQOta3QH6PzmJT4WsI0yfNGiUWYgoYgSOtPURSQMbaCt3DM2Y5mEKqzbKLrhN+S+9Jrtmef1VuBUes8wN6rODUHxI+vDwQ+utRJRRo9U=解密后:taoshihan

java使用公钥加密,php解密:

拿上一步java生成的加密后字符串

<?php$encrypted="Tt1p5XnamZkkVjGn1cVgEIb7U+CP27Xw93JQQUZyc2Up/rJL4Mx+dA8mxkva1a/I64sUTb7QD//8gbss4bZY/DHrLityTt2/QjjQUFYD5/Aa1m1QKUBulWY4/C5so5dm6wrRnjolsIFUbY+RfH4B6hp1taQGBRDum/xEX6OsJ9I=";echo $encrypted."\n";//私钥解密$private_key=file_get_contents("rsa_private_key.pem");$pi_key = openssl_pkey_get_private($private_key); openssl_private_decrypt(base64_decode($encrypted),$decrypted,$pi_key);echo "解密后:\n";echo $decrypted."\n";

执行结果:

Tt1p5XnamZkkVjGn1cVgEIb7U+CP27Xw93JQQUZyc2Up/rJL4Mx+dA8mxkva1a/I64sUTb7QD//8gbss4bZY/DHrLityTt2/QjjQUFYD5/Aa1m1QKUBulWY4/C5so5dm6wrRnjolsIFUbY+RfH4B6hp1taQGBRDum/xEX6OsJ9I=解密后:taoshihan

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。