"Go" Java to do RSA plus decryption of those things to consider

Source: Internet
Author: User
Tags array to string base64 decrypt decrypt text string back

"Go" Java to do RSA plus decryption of those things to consider

1. Encrypted systems do not have decryption capabilities, otherwise RSA may not be appropriate

Public key encryption, private key decryption. The encrypted system is deployed separately from the decrypted system, and the encrypted system should not be decrypted at the same time, so that even if the hacker breaks the encryption system, he gets only a bunch of ciphertext data that cannot be cracked. Otherwise, you will have to consider whether your scene is necessary to use RSA.

2. You can adjust the cipher length by modifying the length of the generated key

The length of the cipher generated is equal to the key length. The greater the length of the key, the greater the length of the cipher, and the slower the encryption, and the more difficult the cipher is to be cracked. The famous "safety and efficiency is always a double-edged sword" law, here to show the incisively and vividly. We must make a balanced choice between "security" and "encryption and decryption efficiency" by defining the length of the key.

3. The length of the ciphertext generated is independent of the length of the plaintext, but the plaintext length cannot exceed the key length

The length of ciphertext generated by RSA is always fixed, regardless of the length of the plaintext.
However, the plaintext length cannot exceed the key length. For example, the Java default RSA encryption implementation does not allow the plaintext length to exceed the key length minus 11 (in bytes, that is, byte). That is, if we define the key (we can define the key length by java.security.KeyPairGenerator.initialize (int keysize)) The length is 1024 (in bits, that is, bit), The generated key length is 1024 bits per 8 bits per byte = 128 bytes, then we need to encrypt the plaintext length must not exceed 128 bytes-
11 bytes = 117 bytes. That is, we can encrypt the plaintext of 117 bytes in length, otherwise it will be a problem (such as Javax.crypto.IllegalBlockSizeException:Data must not being longer than bytes< /c0> of the exception).
The RSA plaintext length is the maximum key length that can be supported by the BC provided encryption algorithm.

4. Byte[].tostring () is actually the memory address, not the actual contents of the array converted to String

beware of the ToString trap : The ToString () method of the array in Java returns not the array contents, it returns the type of the array storage element and an identity of the array in the memory location.
Most people fall into this myth without knowing it, including some old birds who have written for years in Java. For example, this blog "How to Convert byte[" Array to String in Java code

public class testbyte{public    static void Main (string[] argv) {     String example = "This is an example";    byte[] bytes = Example.getbytes ();     System.out.println ("Text:" + example);    System.out.println ("Text [Byte Format]:" + bytes);    System.out.println ("Text [Byte Format]:" + bytes.tostring ());     string s = new string (bytes);    System.out.println ("Text decryted:" + s);}  }


Output:
Text:this is an example
Text [Byte Format]: [[email protected]
Text [Byte Format]: [[email protected]
Text Decryted:this is an example
And the code in this blog, "RSA encryption Example."

Final byte[] ciphertext = Encrypt (Originaltext, publickey); System.out.println ("Encrypted:" +ciphertext.tostring ());


Output:
[[Email protected]
These outputs are actually an identifier for the byte array in the memory location, rather than the string content that the author considers a byte array to convert to. If we persist the key with byte[].tostring () or in JSON with some other string, the decryption of the key will only get a string of meaningless characters, and when he decodes it it is likely to encounter " Javax.crypto.BadPaddingException"exception.

5. String to hold text information, byte array to hold binary data

Java.lang.String saves plaintext, byte arrays save binary ciphertext, and there should be no conversion between java.lang.String and byte[]. If you do have to use java.lang.String to hold these binary data, the safest way is to use BASE64 (recommended Apache Commons-codec Library ORG.APACHE.COMMONS.CODEC.BINARY.BASE64):

      Use String to hold cipher binary data      Base64 base64 = new Base64 ();       String cipherTextBase64 = base64.encodetostring (ciphertext);            Get cipher binary data back from String      byte[] Ciphertextarray = Base64.decode (cipherTextBase64);

6. Each cipher generated is inconsistent to prove that the encryption algorithm you choose is safe

A good encryption must be generated each time the ciphertext are inconsistent, even if each time you clear the same public key. Because of this, the plaintext information can be more safely hidden.
Java default RSA implementation is "rsa/none/pkcs1padding" (such as Cipher Cipher = cipher.getinstance ("RSA"), the Cipher generated ciphertext is always inconsistent), bouncy Cas The default RSA implementation for Tle is "rsa/none/nopadding".
Why is the Java default RSA implementation inconsistent with each generation of ciphertext, even if the same plaintext, the same public key is used every time? This is because the PKCS #1 padding scheme of RSA fills the plaintext information with random numbers before it is encrypted.
You can use the following methods to generate the same ciphertext each time, but you must realize the cost of doing so. For example, you might use RSA to encrypt the transmission, but because of the same ciphertext generated each time by your same plaintext, an attacker could then identify when the same message was sent.

Security.addprovider (New Org.bouncycastle.jce.provider.BouncyCastleProvider ()); final Cipher Cipher = Cipher.getinstance ("rsa/none/nopadding", "BC");

7. You can reduce the length of the ciphertext by adjusting the algorithm provider

The Java default RSA implementation "Rsa/none/pkcs1padding" requires a minimum key length of 512 bits (otherwise it will be reported Java.security.InvalidParameterException:RSA keys must be At least ), which means that the generated key, ciphertext length is 64 bytes minimum. If you are too big, you can reduce the ciphertext length by adjusting the algorithm provider:

Security.addprovider (New Org.bouncycastle.jce.provider.BouncyCastleProvider ()); final Keypairgenerator KeyGen = Keypairgenerator.getinstance ("RSA", "BC"); keygen.initialize (128);

The resulting ciphertext length is 128 bits (16 bytes). But before doing so, please review the 2nd of this article.

8. Cipher is stateful and thread insecure

Javax.crypto.Cipher is stateful, do not treat Cipher as a static variable unless your program is single-threaded, which means you can guarantee that only one thread is calling Cipher at the same time. Otherwise you may encounter java.lang.ArrayIndexOutOfBoundsException:too much data for RSA block exception like the author. To meet this anomaly, you need to first determine if the plaintext (or ciphertext) you are encrypting to Cipher is too long, and if the plaintext (or cipher) is too long, you need to consider whether your Cipher thread is unsafe.

Postscript

Although "RSA encryption Example" has some misunderstanding, but I still think it is a very good entry-level article. Combined with the contents of this article, the author has made some adjustments to the code for reference:

Import Java.io.file;import Java.io.fileinputstream;import Java.io.filenotfoundexception;import Java.io.fileoutputstream;import Java.io.ioexception;import Java.io.objectinputstream;import Java.io.objectoutputstream;import Java.security.keypair;import Java.security.keypairgenerator;import Java.security.nosuchalgorithmexception;import Java.security.privatekey;import Java.security.PublicKey;import Java.security.security;import Javax.crypto.cipher;import org.apache.commons.codec.binary.base64;/** * @author Javadigest * */public class Encryptionutil {/** * String to hold name of the encryption algorithm. */public Static final string algorithm = "RSA";/** * string to hold name of the encryption padding. */public static final String PADDING = "rsa/none/nopadding";/** * string to hold name of the security provider. */public static final String PROVIDER = "BC";/** * string to hold the name of the private key file. */public static final String private_key_file = "E:/defonds/work/20150116/private. Key ";/** * String to hold name of the public key file. */public static final String public_key_file = "E:/defonds/work/20150116/public.key";/** * Generate KEY which contains a P Air of private and public key using the 1024x768 * bytes. Store the set of keys in Prvate.key and Public.key files. * * @throws nosuchalgorithmexception * @throws ioexception * @throws filenotfoundexception */public static void Generatek EY () {try {security.addprovider (New Org.bouncycastle.jce.provider.BouncyCastleProvider ())); final Keypairgenerator KeyGen = keypairgenerator.getinstance (algorithm, PROVIDER); Keygen.initialize (n); final KeyPair key = Keygen.generatekeypair (); File Privatekeyfile = new file (private_key_file); File Publickeyfile = new file (public_key_file);//Create files to store public and private Keyif (privatekeyfile.getparent File () = null) {Privatekeyfile.getparentfile (). Mkdirs ();} Privatekeyfile.createnewfile (); if (publickeyfile.getparentfile () = null) {Publickeyfile.getparentfile (). Mkdirs (); PublickeYfile.createnewfile ();//Saving the public key in a fileobjectoutputstream Publickeyos = new ObjectOutputStream (New FileOu Tputstream (publickeyfile));p Ublickeyos.writeobject (Key.getpublic ());p ublickeyos.close ();//Saving the Private key In a fileobjectoutputstream Privatekeyos = new ObjectOutputStream (new FileOutputStream (Privatekeyfile)); Privatekeyos.writeobject (Key.getprivate ());p rivatekeyos.close ();} catch (Exception e) {e.printstacktrace ();}} /** * The method checks if the pair of public and private key has been * generated. * * @return flag indicating if the pair of keys were generated. */public static Boolean arekeyspresent () {File Privatekey = new File (private_key_file); File PublicKey = new file (public_key_file), if (Privatekey.exists () && publickey.exists ()) {return true;} return false;} /** * Encrypt The Plain text using public key. * * @param text *: Original plain text * @param key *: The public key * @return Encrypted text * @ Throws Java.lang.ExcEption */public Static byte[] Encrypt (String text, PublicKey key) {byte[] ciphertext = null;try {//Get an RSA cipher obje CT and print the Providersecurity.addprovider (New Org.bouncycastle.jce.provider.BouncyCastleProvider ()); final Cipher cipher = Cipher.getinstance (PADDING, PROVIDER);//Encrypt the plain text using the public keycipher.init (cipher.encrypt_m ODE, key); ciphertext = Cipher.dofinal (Text.getbytes ());} catch (Exception e) {e.printstacktrace ();} return ciphertext;} /** * Decrypt text using private key. * * @param text *: Encrypted text * @param key *: The private key * @return Plain text * @throws ja Va.lang.Exception */public static String decrypt (byte[] text, Privatekey key) {byte[] Dectyptedtext = null;try {//Get an RSA Cipher object and print the Providersecurity.addprovider (New Org.bouncycastle.jce.provider.BouncyCastleProvider () ), final Cipher Cipher = cipher.getinstance (PADDING, PROVIDER);//Decrypt the text using the private Keycipher.init (Cipher. DEcrypt_mode, key);d Ectyptedtext = cipher.dofinal (text);} catch (Exception ex) {ex.printstacktrace ();} return new String (Dectyptedtext);}  /** * Test the encryptionutil */public static void Main (string[] args) {try {//Check if the pair of keys are present else Generate Those.if (!arekeyspresent ()) {//Method generates a pair of keys using the The RSA algorithm and//stores in th EIR respective Filesgeneratekey ();} Final String originaltext = "12345678901234567890123456789012"; ObjectInputStream InputStream = null;//Encrypt the String using the public Keyinputstream = new ObjectInputStream (new FileInputStream (Public_key_file)); final PublicKey PublicKey = (PublicKey) inputstream.readobject (); final byte[] ciphertext = Encrypt (Originaltext, publickey);//Use String to hold cipher binary dataBase64 base64 = new Base64 (); String cipherTextBase64 = base64.encodetostring (ciphertext);//Get cipher binary data back from stringbyte[] Ciphertextar Ray = Base64.decode (CIPHERTEXTBASE64);//Decrypt the CIPHer text using the private Key.inputstream = new ObjectInputStream (new FileInputStream (Private_key_file)); final Privatekey Privatekey = (privatekey) inputstream.readobject (); final String plaintext = Decrypt (Ciphertextarray, Privatekey);//Printing the Original, Encrypted and decrypted TextSystem.out.println ("original=" + originaltext); System.out.println ("encrypted=" + cipherTextBase64); System.out.println ("decrypted=" + plaintext);} catch (Exception e) {e.printstacktrace ();}}}



Sir into a pair of keys for later encryption and decryption use (do not need to generate a key every time encryption), the key length is 256 bits, that is, the resulting ciphertext length is 32 bytes, support encryption maximum length of 32 bytes of clear text, because the use of nopadding so the same key in the same plaintext, This article always generates the same ciphertext, then encrypts the plaintext information you provide using the generated public key, generates 32-byte binary plaintext, and then converts the binary ciphertext to a string by using Base64, and then demonstrates how to convert the Base64 string back into a binary cipher Finally, the binary ciphertext is converted to plaintext before encryption. The above program output is as follows:
original=12345678901234567890123456789012
Encrypted=gtyx3nlo9vsemj+rb/dnrzp9xehczfkhpgtazka8acc=
decrypted=12345678901234567890123456789012

Resources
    • Http://www.bouncycastle.org/wiki/display/JA1/Frequently+Asked+Questions
    • Http://stackoverflow.com/questions/1536054/how-to-convert-byte-array-to-string-and-vice-versa
    • Http://www.experts-exchange.com/Security/Encryption/Q_26980724.html
    • Http://stackoverflow.com/questions/17497426/why-does-rsa-produce-different-results-with-same-key-and-message

"Go" Java to do RSA plus decryption of those things to consider

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.