# RSA encryption and decryption

## 3. Experimental principle

RSA public key cryptosystem is a cryptosystem that uses different encryption keys and decryption keys, and "it is computationally infeasible to derive a decryption key from a known encryption key".

In the public key cryptosystem, the encryption key (ie the public key) PK is public information, and the decryption key (ie the secret key) SK needs to be kept secret. Both encryption algorithm E and decryption algorithm D are also public. Although the decryption key SK is determined by the public key PK, SK cannot be calculated from the PK.

The principle of     RSA public key cryptosystem is: According to number theory, it is relatively easy to find two large prime numbers, but it is extremely difficult to factorize their product, so the product can be made public as an encryption key.

The security of     RSA depends on the decomposition of large numbers, but whether it is equivalent to the decomposition of large numbers has not been proved theoretically, nor has it been theoretically proved to be deciphered. The difficulty of RSA is equivalent to the difficulty of factoring large numbers. Because there is no proof that cracking RSA requires large number factorization. Assuming that there is an algorithm that does not need to factorize large numbers, it can definitely be modified into a large number factorization algorithm, that is, the major defect of RSA is that it is impossible to theoretically grasp its confidentiality performance, and most people in the cryptography community tend to factor decomposition instead of NPC question.

The secrecy strength of the     RSA algorithm increases with the length of its key. However, the longer the key, the longer it takes to encrypt and decrypt. Therefore, it should be comprehensively considered according to the sensitivity of the protected information, the unworthiness of the attacker's cost of cracking, and the response time required by the system, especially in the field of business information.

## 4. Experimental record

BytesHexConverter.java code:

```package key;

public class BytesHexConverter {
public static byte[] hexToBytes(String hex) {
hex = hex.length() % 2 != 0 ? "0" + hex : hex;

byte[] b = new byte[hex.length() / 2];
for (int i = 0; i < b.length; i++) {
int index = i * 2;
int v = Integer.parseInt(hex.substring(index, index + 2), 16);
b[i] = (byte) v;
}
return b;
}

public static String byteToHex(byte[] bytes){
String strHex = "";
StringBuilder sb = new StringBuilder("");
for (int n = 0; n < bytes.length; n++) {
strHex = Integer.toHexString(bytes[n] & 0xFF);
sb.append((strHex.length() == 1) ? "0" + strHex : strHex); // Each byte is represented by two characters, the number of digits is not enough, and the high-order bits are filled with 0
}
return sb.toString().trim();
}

}
```

### 1) Generate a random key as the data to be encrypted

Skey_DES.java code:

```package key;

import java.io.*;
import javax.crypto.*;

public class Skey_DES

{//Symmetric key generation and save in file through object serialization

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

{

KeyGenerator kg=KeyGenerator.getInstance("DESede");//Create a key generator

kg.init(168);//Initialize the key generator

SecretKey k=kg.generateKey( );//generate key

//Save the key in a file via object serialization

String secretKeyContent = BytesHexConverter.byteToHex(k.getEncoded());

System.out.println(secretKeyContent);

FileOutputStream  f1=new FileOutputStream("c:/A/Key.dat");
ObjectOutputStream b1=new  ObjectOutputStream(f1);
b1.writeObject(k);
}
}
```

key: the key to be encrypted

Figure 1. Generated key to be encrypted

### 2) Generate a public-private key pair

Skey_RSA.java code:

```package key;

import java.io.*;
import java.security.*;

public class Skey_RSA {

public static void main(String[] args) throws Exception{
//???????????KeyPairGenerator?????????????????RSA,DSA
KeyPairGenerator kpg=KeyPairGenerator.getInstance("RSA");

kpg.initialize(1024);

KeyPair kp=kpg.genKeyPair();
PublicKey pbkey=kp.getPublic();
PrivateKey prkey=kp.getPrivate();
FileOutputStream  f1=new FileOutputStream("c:/A/Skey_RSA_pub.dat");
ObjectOutputStream b1=new ObjectOutputStream(f1);
b1.writeObject(pbkey);
FileOutputStream  f2=new FileOutputStream("c:/B/Skey_RSA_priv.dat");
ObjectOutputStream b2=new ObjectOutputStream(f2);
b2.writeObject(prkey);

}

}
```

Figure 2. Skey_RSA_pub.dat is the generated public key

Figure 3. Generated private key for Skey_RSA_priv.dat

### 3) Encrypt Key.dat with the public key

Enc_RSA.java code:

```package key;

import javax.crypto.SecretKey;
import java.security.interfaces.RSAPublicKey;
import java.math.*;
import java.io.*;
public class Enc_RSA {

public static void main(String[] args) throws Exception{
FileInputStream fileInputStream= new FileInputStream("c:/A/Key.dat");
ObjectInputStream a=new ObjectInputStream(fileInputStream);
FileInputStream f=new FileInputStream("c:/A/Skey_RSA_pub.dat");
ObjectInputStream b=new ObjectInputStream(f);
//Convert public key to RSA public key
//Get public key parameters: the integer e corresponding to the public key, the integer n used for modulo
BigInteger e=pbk.getPublicExponent();
BigInteger n=pbk.getModulus();
System.out.println("e="+e);
System.out.println("n="+n);
byte ptext[]=key.getEncoded();
System.out.println(BytesHexConverter.byteToHex(ptext));
BigInteger m=new BigInteger(ptext);
BigInteger c=m.modPow(e,n);
System.out.println("c="+c);
String cs=c.toString();
BufferedWriter out=
new BufferedWriter(new OutputStreamWriter(new FileOutputStream("Enc_RSA.dat")));
out.write(cs,0,cs.length());
out.close();

}

}
```

Figure 4. Encryption result, where e is the public key parameter, n is the integer used for modulo, and c is the encrypted data

### 4) decrypt c using the private key

Dec_RSA.java code:

```package key;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.interfaces.*;
import java.math.*;
import java.io.*;
public class Dec_RSA {

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

BigInteger c=new BigInteger(ctext);
FileInputStream f=new FileInputStream("c:/B/Skey_RSA_priv.dat");
ObjectInputStream b=new ObjectInputStream(f);
BigInteger d=prk.getPrivateExponent();
BigInteger n=prk.getModulus();
System.out.println("d="+d);
System.out.println("n="+n);

BigInteger m=c.modPow(d, n);
System.out.println("m="+m);
byte[]mt=m.toByteArray();
SecretKey key=new SecretKeySpec(mt,"DESede");
System.out.println("new key="+BytesHexConverter.byteToHex(key.getEncoded()));
System.out.println("Plain Text is");
FileOutputStream f1=new FileOutputStream("c:/B/Key.dat");
ObjectOutputStream b1=new ObjectOutputStream(f1);
b1.writeObject(key);
b1.close();
f1.close();
//	for(int i=0;i<mt.length;i++){
//		System.out.print((char)mt[i]);
//		FileOutputStream f1=new FileOutputStream("c:/B/Key.dat");
//		ObjectOutputStream b1=new ObjectOutputStream(f1);
//		b1.writeObject(m);
//	}
}

}
```

Figure 5. Decryption result, where d is the private key parameter, n is the integer of the modulo, m is the Euler function of n, and new key is the decrypted key

Posted by renzaho on Sat, 07 May 2022 18:43:42 +0300