Simple definition: public key and private key. Encryption and decryption use two different keys, so they are asymmetric.
System: ubuntu 14.04
Software: openssl java php
Generating public key and private key
Use commands to generate private keys:
openssl genrsa -out rsa_private_key.pem 1024
Parameter: genrsa generated key - out output to file rsa_private_key.pem file name 1024 length
Extract the public key from the private key:
openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
Parameters: RSA extracts public key - in reads in the file rsa_private_key.pem file name - pubout output - out to the file rsa_public_key.pem file name
shell encryption and decryption
Create a new readme.txt content for taoshihan
Use public key encryption:
openssl rsautl -encrypt -in readme.txt -inkey rsa_public_key.pem -pubin -out hello.en
Parameters: rsautl encryption and decryption - encrypt encryption - in from file input readme.txt file name - in key input key rsa_public_key.pem public key generated in the previous step - pubin table name input is public key file - out output to file hello.en output file name
Decrypt with a private key:
openssl rsautl -decrypt -in hello.en -inkey rsa_private_key.pem -out hello.de
Parameter: - decrypt decryption - in from the file input hello.en encryption file generated in the previous step - in key input key rsa_private_key.pem generated in the previous step - out output to the file output hello.de file name
cat hello.de // taoshihan
php encryption and decryption
$profile="taoshihan"; echo "Before encryption:{$profile}\n"; //Public key encryption $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);//Because the encrypted code is scrambled,therefore base64 Once echo "After encryption:\n"; echo $encrypted."\n"; //Private key decryption $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 "After decryption:\n"; echo $decrypted."\n";
New rsa.php file
Post-implementation results:
Before encryption:taoshihan //After encryption: ShjsdlTceurVfO0ocENqHGl9RXrQRm3vuprqchhuVOdX1ldJC2O2sIvjjpQfPWOkF1WA+tqdyIl9YJQ0/2DqAp4zaqI1TCNsXduGn2iUZQ88g7B5eSI7r/iWKcX527pLe95EBvFMw/D65tlYscI5RClcp3KrOw2fqDQZ3D3nKAI= //After decryption: taoshihan
java encryption and decryption:
Prepare the jar package bcprov-ext-jdk15on-156.jar
wget http://www.bouncycastle.org/download/bcprov-ext-jdk15on-156.jar
RSAEncrypt.java file
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 key */ private RSAPrivateKey privateKey; /** * public key */ private RSAPublicKey publicKey; /** * Byte Data to String Special Set */ private static final char[] HEX_CHAR= {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; /** * Get private key * @return Current private key object */ public RSAPrivateKey getPrivateKey() { return privateKey; } /** * Get public key * @return Current public key objects */ public RSAPublicKey getPublicKey() { return publicKey; } /** * Random Generation of Key Pairs */ 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(); } /** * Loading the public key from the input stream in the file * @param in Public key input stream * @throws Exception Exceptions generated when loading public keys */ 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("Public Key Data Stream Reading Error"); } catch (NullPointerException e) { throw new Exception("The public key input stream is empty"); } } /** * Loading public keys from strings * @param publicKeyStr Public key data string * @throws Exception Exceptions generated when loading public keys */ 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("No algorithm is available."); } catch (InvalidKeySpecException e) { throw new Exception("Illegal public key"); } catch (IOException e) { throw new Exception("Public Key Data Content Reading Error"); } catch (NullPointerException e) { throw new Exception("The public key data is empty"); } } /** * Loading private keys from files * @param keyFileName Private key file name * @return Success * @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("Private Key Data Reading Error"); } catch (NullPointerException e) { throw new Exception("The private key input stream is empty"); } } 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("No algorithm is available."); } catch (InvalidKeySpecException e) { throw new Exception("Private key illegal"); } catch (IOException e) { throw new Exception("Private Key Data Content Reading Error"); } catch (NullPointerException e) { throw new Exception("Private key data is empty"); } } /** * Encryption process * @param publicKey public key * @param plainTextData plaintext * @return * @throws Exception Exceptional Information in Encryption */ public byte[] encrypt(RSAPublicKey publicKey, byte[] plainTextData) throws Exception{ if(publicKey== null){ throw new Exception("Encrypted public key is empty, Please set up"); } 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("No such encryption algorithm"); } catch (NoSuchPaddingException e) { e.printStackTrace(); return null; }catch (InvalidKeyException e) { throw new Exception("Illegal Encryption Public Key,Please check."); } catch (IllegalBlockSizeException e) { throw new Exception("Illegal length of plaintext"); } catch (BadPaddingException e) { throw new Exception("Clear data corrupted"); } } /** * decryption * @param privateKey private key * @param cipherData Ciphertext data * @return Plaintext * @throws Exception Abnormal information in decryption process */ public byte[] decrypt(RSAPrivateKey privateKey, byte[] cipherData) throws Exception{ if (privateKey== null){ throw new Exception("Decrypt the private key to be empty, Please set up"); } 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("No decryption algorithm"); } catch (NoSuchPaddingException e) { e.printStackTrace(); return null; }catch (InvalidKeyException e) { throw new Exception("Illegal decryption of private key,Please check."); } catch (IllegalBlockSizeException e) { throw new Exception("Illegal length of ciphertext"); } catch (BadPaddingException e) { throw new Exception("Ciphertext data corrupted"); } } /** * Byte data to hexadecimal string * @param data Input data * @return Hexadecimal content */ public static String byteArrayToString(byte[] data){ StringBuilder stringBuilder= new StringBuilder(); for (int i=0; i<data.length; i++){ //Remove the high four bits of bytes as an index to get the corresponding hexadecimal identifier. Note the unsigned right shift. stringBuilder.append(HEX_CHAR[(data[i] & 0xf0)>>> 4]); //Remove the lower four bits of bytes as an index to get the corresponding hexadecimal identifier 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(); //Loading public key try { rsaEncrypt.loadPublicKey(new FileInputStream("rsa_public_key.pem")); System.out.println("Successful loading of public key"); } catch (Exception e) { System.err.println(e.getMessage()); System.err.println("Failure to load public key"); } //Loading private key try { rsaEncrypt.loadPrivateKey(new FileInputStream("rsa_private_key.pem")); System.out.println("Successful loading of private key"); } catch (Exception e) { System.err.println(e.getMessage()); System.err.println("Failure to load private key"); } //Test string String encryptStr= "taoshihan"; System.out.println("Before encryption:"); System.out.println(encryptStr); try { //encryption byte[] cipher = rsaEncrypt.encrypt(rsaEncrypt.getPublicKey(), encryptStr.getBytes()); //Decrypt byte[] plainText = rsaEncrypt.decrypt(rsaEncrypt.getPrivateKey(), cipher); BASE64Encoder encode = new BASE64Encoder(); String buffer= encode.encode(cipher); System.out.println("After encryption:"); System.out.println(new String(buffer)); System.out.println("After decryption:"); System.out.println(new String(plainText)); } catch (Exception e) { System.err.println(e.getMessage()); } } }
Compilation and execution with packages
javac -cp bcprov-ext-jdk15on-156.jar RSAEncrypt.java java -cp .:bcprov-ext-jdk15on-156.jar RSAEncrypt
Implementation results:
Successful loading of public key Successful loading of private key Before encryption: taoshihan After encryption: Tt1p5XnamZkkVjGn1cVgEIb7U+CP27Xw93JQQUZyc2Up/rJL4Mx+dA8mxkva1a/I64sUTb7QD//8 gbss4bZY/DHrLityTt2/QjjQUFYD5/Aa1m1QKUBulWY4/C5so5dm6wrRnjolsIFUbY+RfH4B6hp1 taQGBRDum/xEX6OsJ9I= After decryption: taoshihan
shell is encrypted with public key and php is decrypted with private key
shell:
openssl rsautl -encrypt -in readme.txt -inkey rsa_public_key.pem -pubin|base64 //Encrypted string lNJ50ODiofcp+adrtAI943HOsjdDTg3UMfUkt0NI7DhUjxCM+NAlBH08WVQRtYK9W8ZoQOta3QH6 PzmJT4WsI0yfNGiUWYgoYgSOtPURSQMbaCt3DM2Y5mEKqzbKLrhN+S+9Jrtmef1VuBUes8wN6rOD UHxI+vDwQ+utRJRRo9U=
php:
<?php $encrypted="lNJ50ODiofcp+adrtAI943HOsjdDTg3UMfUkt0NI7DhUjxCM+NAlBH08WVQRtYK9W8ZoQOta3QH6 PzmJT4WsI0yfNGiUWYgoYgSOtPURSQMbaCt3DM2Y5mEKqzbKLrhN+S+9Jrtmef1VuBUes8wN6rOD UHxI+vDwQ+utRJRRo9U="; echo $encrypted."\n"; //Private key decryption $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 "After decryption:\n"; echo $decrypted."\n";
Implementation results:
lNJ50ODiofcp+adrtAI943HOsjdDTg3UMfUkt0NI7DhUjxCM+NAlBH08WVQRtYK9W8ZoQOta3QH6 PzmJT4WsI0yfNGiUWYgoYgSOtPURSQMbaCt3DM2Y5mEKqzbKLrhN+S+9Jrtmef1VuBUes8wN6rOD UHxI+vDwQ+utRJRRo9U= //After decryption: taoshihan
java uses public key encryption and php decryption:
Take the encrypted string generated by java in the previous step
<?php $encrypted="Tt1p5XnamZkkVjGn1cVgEIb7U+CP27Xw93JQQUZyc2Up/rJL4Mx+dA8mxkva1a/I64sUTb7QD//8 gbss4bZY/DHrLityTt2/QjjQUFYD5/Aa1m1QKUBulWY4/C5so5dm6wrRnjolsIFUbY+RfH4B6hp1 taQGBRDum/xEX6OsJ9I="; echo $encrypted."\n"; //Private key decryption $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 "After decryption:\n"; echo $decrypted."\n";
Implementation results:
Tt1p5XnamZkkVjGn1cVgEIb7U+CP27Xw93JQQUZyc2Up/rJL4Mx+dA8mxkva1a/I64sUTb7QD//8 gbss4bZY/DHrLityTt2/QjjQUFYD5/Aa1m1QKUBulWY4/C5so5dm6wrRnjolsIFUbY+RfH4B6hp1 taQGBRDum/xEX6OsJ9I= //After decryption: taoshihan