RSA public key encryption to obtain multi-factor 00 JavaWeb result of the use of RSA

EDITORIAL

This article is resolved in encryption and decryption are not using one, the problem is not the last byte array to find the same when a key pair is generated its own tools for key issues, but this article RSA public key encryption and public key index get coefficient (byte [] section) more detailed explanation, although the last is useless in this way. Here's how I used. digit indeed wrong, but does not affect the reception generate a public key and a coefficient index, does not affect the background decryption, just to make a record.

//         // Get the public key and the public exponent coefficient
 //         // Get public Object - Note: the front end side and the need to use a public key exponent coefficient
 //         RSAPublicKey RSAUtils.getDefaultPublicKey publicKey = ();
 //         // public Key - coefficient (n-)
 //         request.setAttribute ( "pkModulus", new new String (Hex.encode (publicKey.getModulus () the toByteArray ())).);
 //         // public - index (E1)
 //         request.setAttribute (. "pkExponent", new new String (Hex.encode (publicKey.getPublicExponent () the toByteArray ())));
         // obtains the public key and the public exponent coefficient
         // public - coefficient (n-) 
        RSAPublicKey publicKey = RSAUtils.aPublic;
        String pkModulus2 = publicKey.getModulus().toString(16);
        request.setAttribute("pkModulus", pkModulus2);
        //公钥-指数(e1)
        String pkExponent2 = publicKey.getPublicExponent().toString(16);
        request.setAttribute("pkExponent", pkExponent2);

Contrast BigInteger converted to hexadecimal String way

method one

. String pkModulus2 = publicKey.getModulus () toString (16); coefficients generated public key (256)

e0ffbc04ee1c099b3e898359a12a3d1a307415ec3daaff86e3d1b61a7d434e5073de79bc7de12324d4643fb93923f007897c35b7bb98c2864b8e4d319a5028935f882fad6ba1df8181478a331cf7d59335a603262bf7ad5aa648869ebd348640ad95f389eb603b6e301ea3e7aff24dc58209c2eef449a2bbe8d6d2159cdf1383

Second way

String pkModulus = new String (Hex.encode (publicKey.getModulus () toByteArray ()).); Coefficients generated public key 258, the difference is more than the foregoing 00

00e0ffbc04ee1c099b3e898359a12a3d1a307415ec3daaff86e3d1b61a7d434e5073de79bc7de12324d4643fb93923f007897c35b7bb98c2864b8e4d319a5028935f882fad6ba1df8181478a331cf7d59335a603262bf7ad5aa648869ebd348640ad95f389eb603b6e301ea3e7aff24dc58209c2eef449a2bbe8d6d2159cdf1383

 

The BigInteger toString (int radix) Method

/**
     * Returns the String representation of this BigInteger in the
     * given radix.  If the radix is outside the range from {@link
     * Character#MIN_RADIX} to {@link Character#MAX_RADIX} inclusive,
     * it will default to 10 (as is the case for
     * {@code Integer.toString}).  The digit-to-character mapping
     * provided by {@code Character.forDigit} is used, and a minus
     * sign is prepended if appropriate.  (This representation is
     * compatible with the {@link #BigInteger(String, int) (String,
     * int)} constructor.)
     *
     * @param  radix  radix of the String representation.
     * @return String representation of this BigInteger in the given radix.
     * @see    Integer#toString
     * @see    Character#forDigit
     * @see    #BigInteger(java.lang.String, int)
     */
    public String toString(int radix) {
        if (signum == 0)
            return "0";
        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
            radix = 10;

        // If it's small enough, use smallToString.
        if (mag.length <= SCHOENHAGE_BASE_CONVERSION_THRESHOLD)
           return smallToString(radix);

        // Otherwise use recursive toString, which requires positive arguments.
        // The results will be concatenated into this StringBuilder
        StringBuilder sb = new StringBuilder();
        if (signum < 0) {
            toString(this.negate(), sb, radix, 0);
            sb.insert(0, '-');
        }
        else
            toString(this, sb, radix, 0);

        return sb.toString();
    }

Described in jdk1.8

statement

Following switched: JavaWeb use of RSA

Because of the company's web page form is submitted plaintext post, although it is https pages, but still a bit hidden (https will not be black? Anyway, expressly to force the grid is a point of difference you have to admit ah), told me to get on top of it a RSA encryption, client JS encryption and decryption JAVA server .

This article is intended want javaweb / java applications which use people of RSA.

 

A, RSA is ShenMeGui:

In fact, beginning with RSA encryption told me I was rejected, because you can not call me by I use, I have to look up what he is right.

RSA is the most influential public key encryption algorithm, a non-symmetric encryption, that is, we all know with a public key to encrypt out of the ciphertext, only people who have the private key to unlock now heard 1024 safer, 2048, it is quite safe, it is more difficult to break up.

About the basic principles of RSA, which referred to Baidu Encyclopedia " RSA algorithm is based on a very simple arithmetical fact: multiplying two large prime numbers is very easy, but factoring want their product is extremely difficult, so it can be multiplication as a public encryption key. "then Mr. Ruan Yifeng's  " RSA algorithm principle (a) " and " RSA algorithm principle (B) " which would explain more clearly, watching you probably understand (indeed Daniel acridine) . Ruan mentioned:

Encryption formula :

me ≡ c (mod n)

Decryption formula :

cd ≡ m (mod n)

n is the public modulus, which is the product pq, e is a public key of the index, d is the private exponent , below we will discuss the use of public and private keys can restore them.

If you know how it is, then it is clear how the RSA is going on, not sure about it, please see the article, here is mainly to say how to use RSA rather than trying to achieve RSA. RSA will know about the principles of the code we write helpful, or you get it working myself out of the question, are we supposed to?

Second, the use of RSA encryption and decryption of ideas:

Speaking of the idea is relatively simple. In fact, to get the browser to the server's public key, after filling in user information, encrypted with the public key to help users, and then submitted, java server then decrypt it ....... Right? Originally general idea is right, but the way I found no way to direct and public transport available, so we have to use the above formula, e and n take out the first use of the e and n js reduced to public and then he gave after the submission of information encryption, finally is to use java on the server to decrypt.

Third, the specific embodiment of the method:

Said so much, then dry it benefits someone else to write the code? Yes I know you want this.

I was beginning to find out about after RSA began looking for a variety of code to refer to , so under my tireless efforts, so I found this "for RSA encryption and decryption using javascript and the Java" , overall is available, and the overall idea and I agreed, but still a lot of problems with them, you can look at the code before opening the link.

Four, javascript inside RSA:

First you need three js

BigInt.js   - used to generate a large integer; (which is required for the RSA algorithm)
RSA.js     - the main algorithm of RSA;
Barrett.js  - a support document RSA algorithm need to use;

As mentioned above, you have a public key e and n can restore the public key, and then encrypted. The key code is as follows:

// setMaxDigits () looks like a maximum number of bits to generate the ciphertext, if not set or set, then chaos is likely to lead to an infinite loop and then the browser to crash.
// This statement must be executed first, passed in 1024 to 130,2048 key words to pass 260
setMaxDigits(130);
// RSAKeyPair key pair is an object, can be generated with a public key e and n, in fact, the second parameter d, because we only need to pass the public key of course is empty.
key&nbsp;=&nbsp;new &nbsp;RSAKeyPair(e,"",n);
// This encryption method is relatively simple, and the original public key is passed, into ciphertext.
var result = encryptedString(key, document.getElementById("pwd").value);
 

e n and where they come from? You can first use the link inside to test it, I think it should be a normal java js to read to, the following will be mentioned.

Five, java inside RSA:

I'm sure that java is also related classes and API use of RSA, what do we need it? What we need is inside the JDK java.security package and an open source encryption solution for the BouncyCastle API's. java.security you can import your own, → the BouncyCastle here ← to JDK15 above, at the latest you can, or can not be found on Baidu open look slightly ~

Let's talk about the java code issues inside.

First is to generate a key, use generateKeyPair () and saveKey (), can easily generate a pair of keys, you can save directly to the appropriate path can be like me rephrase saveKey () to separate the public and private key storage, you can even directly save the session, so that your website will never be in (I guess the key is updated so that the server workload is slightly larger, not as regular thread) with someone else guess the key, here is my modification over code

public static KeyPair generateKeyPair() throws Exception { 
    try { 
       KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA", BouncyCastleProvider()); 
       final int KEY_SIZE = 1024; // encryption block size, you can change the 2048, but will be very slow ........
       keyPairGen.initialize(KEY_SIZE, new SecureRandom()); 
       KeyPair keyPair = keyPairGen.generateKeyPair(); 
       return keyPair; 
    } catch (Exception e) { 
    throw new Exception(e.getMessage()); 
    } 
}

Besides taking key problem, you can use getKeyPair () to obtain public and private keys, probably a long way (my colleagues to help modify the next, and then return the object itself from compulsory conversion to) here note readObject encryption package and will in fact relationship.

     FileInputStream fis = new FileInputStream(path); 
     ObjectInputStream oos = new ObjectInputStream (fis); 
     Object kp=  oos.readObject(); 
     oos.close (); 
     fis.close(); 
     return kp; 
}  
// use him to get the key, if you are this path corresponds to the public key or key, you can also take out directly and then cast into RSAPublicKey or RSAPrivateKey
KeyPair kp=(KeyPair)getKey("D:/key.key");

We read the public key, the need to use getModulus RSAPublicKey () and getPublicExponent () method to obtain the public key e (Exponent) and n (Modulus) given to the front page, the distal end may be received by getparameter the like, or in the page initialized with ajax request.

String Modulus=RSAPublicKey.getModulus().toString(16);
String Exponent=RSAPublicKey.getPublicExponent().toString(16);

It should toString (16) put him into hexadecimal, for front-end use.

The last is the most important part of decryption (encryption and decryption wording is very similar, needy students can take a look decrypt), Best wording is simple and typical of such (raw ciphertext)

public static byte[] RSAdecrypt(PrivateKey pk, byte[] raw) throws Exception {
    Cipher cipher = Cipher.getInstance("RSA", new BouncyCastleProvider());
    cipher.init(Cipher.DECRYPT_MODE, pk); 
    return cipher.doFinal(raw);
}

Then I found online demo like this

  Cipher cipher = Cipher.getInstance("RSA", new BouncyCastleProvider());
  cipher.init(Cipher.DECRYPT_MODE, pk);      
  ByteArrayOutputStream bout = null;
  try {
    bout = new ByteArrayOutputStream(64);
    int j = 0;
    int blockSize = cipher.getBlockSize();
    while (raw.length - j * blockSize > 0) {
      bout.write(cipher.doFinal(raw, j * blockSize, blockSize));
       j++;
    }
    return bout.toByteArray();
  } // followed by catch and the finally, the safe handling bout, not posted
}

This view looks like the second a little safe, but I do not really understand why write so complicated, measured under the running time of almost looks like. We seek guidance.

Here the core of the encryption algorithm used in class Cipher class , I feel the need to probably look at it, it's used in the encryption and decryption processes are doFinal () method, as it is the encryption or decryption time depends on init parameters Cliper the MODE. If not then I said BouncyCastle API you have to use Cipher.getInstance (keyFactory.getAlgorithm ()) to instantiate Clipher, and will be a little trouble.

Here the encryption and decryption has been completed ~ ~ ~ and then the next you may encounter some problems, please see ↓

Sixth, it has encountered a problem, say good after-sales service it?

(1) First mention about setMaxDigits (), which pay attention to the parameters, corresponding to 1024 bits corresponding to 260 130,2048.

(2) Then there are questions about java parameters sent to decrypt the exception: if in full accordance with the above method, or online information practices inside, will appear in the case of large-scale use of the following error.

If you are a streamlined version of RSAdecrypt

org.bouncycastle.crypto.DataLengthException: input too large for RSA cipher.
at org.bouncycastle.crypto.engines.RSACoreEngine.convertInput(Unknown Source)
at org.bouncycastle.crypto.engines.RSABlindedEngine.processBlock(Unknown Source)
at org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi.engineDoFinal(Unknown Source)
at javax.crypto.Cipher.doFinal(Cipher.java:2087)

If you are using complex version of RSAdecrypt

 at javax.crypto.Cipher.doFinal(Cipher.java:2141)
 at com.dimeng.p2p.yylh.util.SecurityHelper.RSAdecrypt(SecurityHelper.java:236)
 at com.dimeng.p2p.yylh.util.SecurityHelper.getdecryptStr(SecurityHelper.java:262)
 at com.dimeng.p2p.yylh.util.SecurityHelper.main(SecurityHelper.java:342)
Exception in thread "main" java.lang.IllegalArgumentException: Bad arguments
 at javax.crypto.Cipher.doFinal(Cipher.java:2141)

The reason is that the usage of online information which is this, the problem lies in toByteArray () above

// result is a string of ciphertext
byte[] en_result = new BigInteger(result, 16).toByteArray();  
byte[] de_result = RSAUtil.decrypt(RSAUtil.getKeyPair().getPrivate(),en_result);  

Precisely because js encrypted when it will lead to byte [] type cipher than the specified amount of time, why? Because the three mentioned above at the time of JS encryption password, occasionally arrive at a correct ciphertext byte [] extra a byte, which is 0, no letters being given a try yourself. Solutions are as follows:

public static byte[] hexStringToBytes(String hexString) {
  if (hexString == null || hexString.equals("")) {
    return null;
  }
  hexString = hexString.toUpperCase();
  int length = hexString.length() / 2;
  char[] hexChars = hexString.toCharArray();
  byte[] d = new byte[length];
  for (int i = 0; i < length; i++) {
    int pos = i * 2;
    d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
  }
  return d;
}

/** * Convert char to byte * @param c char * @return byte */
private static byte charToByte(char c) {
  return (byte) "0123456789ABCDEF".indexOf(c);
}
// this - on the right
byte[] en_result = hexStringToBytes(password_en);

So far wrong problem can be solved

 

Guess you like

Origin www.cnblogs.com/yadongliang/p/12039012.html