Simple case of RSA encryption algorithm




 The RSA encryption algorithm is currently the most influential public key encryption algorithm, and it can resist the vast majority of cryptographic attacks known so far.

  Java

training What are the applications of the RSA encryption algorithm

?
The following is an example of database authentication.

  When using the data set for identity authentication, the password is stored in the database. During authentication, the password entered by the user is the same as the password in the database, and the authentication is passed. If the database is cracked, it will pose a threat to the system. How to ensure the security of the system? It can be applied here. RSA encryption algorithm, encrypts permissions.

  Idea:

  When uploading the username and password in the url, first flip the username and then encrypt it. For example, if the entered password is 12, the actual encrypted value in the background is 21, and then verify with the database, so as to avoid When the database is cracked, the encrypted password of 21 is displayed. When logging in to the system, it is impossible to log in successfully with 21.

  Take the report software FineReport as an example, this is a report software that can read various databases, and display it in client and front-end.

  Implementation scheme:

  1. Put the third-party package used by RSA encryption in the project web-inf/lib folder.

  2. Calling

  the RSA folder of the js file needs to call the js file when encrypting the front-end js, so you need to put Barrett.js, BigInt.js, RSA.js in the project directory, such as: WebReport/js, and put the new js folder into js document.

  3. Define the RSA encryption class

  Define the RSAUtil.java class file, first run the generateKeyPair() method in the class, a random RSAKey.txt file will be generated in the server D drive, and the public key and key will be saved. Refresh the txt file once.

  package com.fr.privilege;

  import java.io.ByteArrayOutputStream;

  import java.io.FileInputStream;

  import java.io.FileOutputStream;

  import java.io.ObjectInputStream;

  import java.io.ObjectOutputStream;

  import java.math.BigInteger;

  import java.security.KeyFactory;

  import java.security.KeyPair;

  import java.security.KeyPairGenerator;

  import java.security.NoSuchAlgorithmException;

  import java.security.PrivateKey;

  import java.security.PublicKey;

  import java.security.SecureRandom;

  import java.security.interfaces.RSAPrivateKey;

  import java.security.interfaces.RSAPublicKey;

  import java.security.spec.InvalidKeySpecException;

  import java.security.spec.RSAPrivateKeySpec;

  import java.security.spec.RSAPublicKeySpec;

  import javax.crypto.Cipher;

  /**

  * RSA utility class. Provides encryption, decryption, key generation, etc. methods.

  * You need to download bcprov-jdk14-123.jar from http://www.bouncycastle.org.

  *

  */

  public class RSAUtil {

  /**

  * * Generate key pair *

  *

  * @return KeyPair *

  * @throws EncryptException

  */

  public static KeyPair generateKeyPair() throws Exception {

  try {

  KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA" ,

  new org.bouncycastle.jce.provider.BouncyCastleProvider());

  final int KEY_SIZE = 1024;// There is nothing to say, this value is related to the size of block encryption and can be changed, but it should not be too large, otherwise the efficiency will be low

  keyPairGen. initialize(KEY_SIZE, new SecureRandom());

  KeyPair keyPair = keyPairGen.generateKeyPair();

  saveKeyPair(keyPair);

  return keyPair;

  } catch (Exception e) {

  throw new Exception(e.getMessage());

  }

  }

  public static KeyPair getKeyPair() throws Exception {

  FileInputStream fis = new FileInputStream("C:/RSAKey.txt");

  ObjectInputStream oos = new ObjectInputStream(fis);

  KeyPair kp = (KeyPair) oos.readObject();

  oos.close();

  fis .close();

  return kp;

  }

  public static void saveKeyPair(KeyPair kp) throws Exception {

  FileOutputStream fos = new FileOutputStream("C:/RSAKey.txt");

  ObjectOutputStream oos = new ObjectOutputStream(fos);

  // 生成密钥

  oos.writeObject(kp);

  oos.close();

  fos.close();

  }

  /**

  * * 生成公钥 *

  *

  * @param modulus *

  * @param publicExponent *

  * @return RSAPublicKey *

  * @throws Exception

  */

  public static RSAPublicKey generateRSAPublicKey(byte[] modulus,

  byte[] publicExponent) throws Exception {

  KeyFactory keyFac = null;

  try {

  keyFac = KeyFactory.getInstance("RSA",

  new org.bouncycastle.jce.provider.BouncyCastleProvider());

  } catch (NoSuchAlgorithmException ex) {

  throw new Exception(ex.getMessage());

  }

  RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger(

  modulus), new BigInteger(publicExponent));

  try {

  return (RSAPublicKey) keyFac.generatePublic(pubKeySpec);

  } catch (InvalidKeySpecException ex) {

  throw new Exception(ex.getMessage());

  }

  }

  /**

  * * 生成私钥 *

  *

  * @param modulus *

  * @param privateExponent *

  * @return RSAPrivateKey *

  * @throws Exception

  */

  public static RSAPrivateKey generateRSAPrivateKey(byte[] modulus,

  byte[] privateExponent) throws Exception {

  KeyFactory keyFac = null;

  try {

  keyFac = KeyFactory.getInstance("RSA",

  new org.bouncycastle.jce.provider.BouncyCastleProvider());

  } catch (NoSuchAlgorithmException ex) {

  throw new Exception(ex.getMessage());

  }

  RSAPrivateKeySpec priKeySpec = new RSAPrivateKeySpec(new BigInteger(

  modulus), new BigInteger(privateExponent));

  try {

  return (RSAPrivateKey) keyFac.generatePrivate(priKeySpec);

  } catch (InvalidKeySpecException ex) {

  throw new Exception(ex.getMessage());

  }

  }

  /**

  * * encryption*

  *

  * @param key

  * encrypted key*

  * @param data

  * plaintext data to be encrypted*

  * @return encrypted data*

  * @throws Exception

  */

  public static byte[] encrypt(PublicKey pk, byte[] data) throws Exception {

  try {

  Cipher cipher = Cipher.getInstance("RSA",

  new org.bouncycastle.jce.provider.BouncyCastleProvider()) ;

  cipher.init(Cipher.ENCRYPT_MODE, pk);

  int blockSize = cipher.getBlockSize();// Get the encrypted block size, for example: the data before encryption is 128 bytes, and key_size=1024

  // The encrypted block size is 127

  / /byte, encrypted to 128 bytes; so there are 2 encrypted blocks in total, the first 127

  // The second byte is 1 byte

  int outputSize = cipher.getOutputSize(data.length);// Get the encrypted block size after encryption

  int leavedSize = data.length % blockSize;

  int blocksSize = leavedSize != 0 ? data. length / blockSize + 1

  : data.length / blockSize;

  byte[] raw = new byte[outputSize * blocksSize];

  int i = 0;

  while (data.length - i * blockSize > 0) {

  if (data.length - i * blockSize > blockSize)

  cipher.doFinal(data, i * blockSize, blockSize, raw, i

  * outputSize);

  else

  cipher.doFinal(data, i * blockSize, data.length - i

  * blockSize, raw, i * outputSize);

  // The doUpdate method is not available here. After viewing the source code, I found that there is no actual action after each doUpdate except putting byte[] in

  // In ByteArrayOutputStream, all byte[] are encrypted at the end of doFinal, but at this time the encrypted block size is likely to have exceeded

  // OutputSize, so we have to use the dofinal method.

  i++;

  }

  return raw;

  } catch (Exception e) {

  throw new Exception(e.getMessage());

  }

  }

  /**

  * * decrypted *

  *

  * @param key

  * decrypted key *

  * @param raw

  * already Encrypted data*

  * @return decrypted plaintext*

  * @throws Exception

  */

  public static byte[] decrypt(PrivateKey pk, byte[] raw) throws Exception {

  try {

  Cipher cipher = Cipher.getInstance("RSA",

  new org.bouncycastle.jce.provider.BouncyCastleProvider());

  cipher.init(cipher.DECRYPT_MODE, pk);

  int blockSize = cipher.getBlockSize();

  ByteArrayOutputStream bout = new ByteArrayOutputStream(64);

  int j = 0;

  while (raw.length - j * blockSize > 0) {

  bout.write(cipher.doFinal(raw, j * blockSize, blockSize));

  j++;

  }

  return bout.toByteArray();

  } catch (Exception e) {

  throw new Exception(e.getMessage());

  }

  }

  /**

  * * *

  *

  * @param args *

  * @throws Exception

  */

  public static void main(String[] args) throws Exception {

  RSAPublicKey rsap = (RSAPublicKey) RSAUtil.generateKeyPair()

  .getPublic();

  String test = "hello world";

  byte[] en_test = encrypt(getKeyPair().getPublic(), test.getBytes());

  System.out.println("123:" + new String(en_test ));

  byte[] de_test = decrypt(getKeyPair().getPrivate(), en_test);

  System.out.println(new String(de_test));

  }

  }

  4. Define password validation class

  Define TestPasswordValidatorRSA.java password validation class

  Definition A class, named TestPasswordValidatorRSA.java, extends AbstractPasswordValidator, rewrites the password verification method encodePassword, first flips the entered password, then encrypts it, and returns the password for verification. The specific code is as follows:

  package com.fr.privilege;

  import com.fr.privilege.providers.dao.AbstractPasswordValidator;

  public class TestPasswordValidatorRSA extends AbstractPasswordValidator{

  //@Override

  public String encodePassword( String clinetPassword) {

  try {

  //Flip the password such as input ab and flip it to ba

  StringBuffer sb = new StringBuffer();

  sb.append(new String(clinetPassword));

  String bb = sb .reverse().toString();

  //Encrypt

  byte[] en_test = RSAUtil.encrypt(RSAUtil.getKeyPair().getPublic(),bb.getBytes());

  //Decrypt, if the data stored in the database is Encryption password, decryption is not required here.

  byte[] de_test = RSAUtil.decrypt(RSAUtil.getKeyPair().getPrivate(),en_test);

  //return encrypted password

  clinetPassword=new String(de_test);

  } catch (Exception e ) {

  // TODO Auto-generated catch block

  e.printStackTrace();

  }

  return clinetPassword; //Get the encrypted password and match it with the database password.

  }

  @Override

  public boolean validatePassword(String arg0, String arg1) {

  // TODO Auto-generated method stub

  return false;

  }

  }

  5. Compile the class file

  First compile the RSAUtil.java class file to generate the RSAKey.txt file on the D drive of the server, Then compile the TestPasswordValidatorRSA.java class, and put the compiled class file in the project project web-inf/classes/com/fr/privilege folder.

  6. Login Login.jsp page settings The

  client requests to the login page and generates a random string. This random string is used as the key encryption password, the following code:

  <%@page contentType="text/html" pageEncoding="UTF- 8"%>

  <%@page import="com.fr.privilege.providers.dao.RSAUtil"%>

  <%!public String Testmo() {

  String module = "";

  try {

  java.security.interfaces.RSAPublicKey rsap = (java.security.interfaces.RSAPublicKey) RSAUtil

  .getKeyPair().getPublic();

  module = rsap.getModulus().toString(16);

  } catch (Exception e) {

  // TODO Auto-generated catch block

  e.printStackTrace();

  }

  return module;

  }%>

  <%!public String Testem() {

  String empoent = "";

  try {

  java.security.interfaces.RSAPublicKey rsap = (java.security.interfaces.RSAPublicKey) RSAUtil

  .getKeyPair().getPublic();

  empoent = rsap.getPublicExponent().toString(16);

  } catch (Exception e) {

  // TODO Auto-generated catch block

  e.printStackTrace();

  }

  return empoent;

  }%>

  <html>

  <head>

  <script type="text/javascript"

  src="ReportServer?op=emb&resource=finereport.js"></script>

  <script type="text/javascript" src="js/RSA.js"></script>

  <script type="text/javascript" src="js/BigInt.js"></script>

  <script type="text/javascript" src="js/Barrett.js"></script>

  <script type="text/javascript">

  function bodyRSA()

  {

  setMaxDigits(130);

  var a = "<%=Testmo()%>";

  var b = "<%=Testem()%>";

  key = new RSAKeyPair(b,"",a);

  }

  function doSubmit() {

  bodyRSA();

  var username = FR.cjkEncode(document.getElementById("username").value); //Get the input username

  var password = FR.cjkEncode(document.getElementById("password").value); //Get the input Parameters

  $.ajax({

  url : "ReportServer?op=auth_login&fr_username=" + username + "&fr_password=" + password, //Send username and password to report authentication address op=auth_login

  data : {__redirect__ : 'false'},

  complete : function(res) {

  var jo = FR.jsonDecode(res.responseText);

  if(jo.url) {

  window.location=jo.url+ "&_=" + new Date().getTime(); //Authentication Jump to the page successfully, because ajax does not support redirecting all settings that need to be jumped

  }

  else{

  alert("Username and password error!" ) //Authentication failed

  }

  }

  })

  }

  </script>

  </head>

  <body>

  <p>

  请登录

  </p>

  <form name="login" method="POST">

  <p>

  用户名:

  <input id="username" type="text" />

  </p>

  <p>

  密 码:

  <input id="password" type="password" />

  </p>

  <input type="button" value="登录" onclick="doSubmit()" />

  </form>

  </body>

  </html>

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326525377&siteId=291194637