我在用Java实现RSA时遇到了下面给出的代码,该代码在解密明文后以数字形式显示明文,但是我希望使用我输入的简单英语.我不想使用Java API.
TestRsa.Java
import java.io.IOException;
import java.math.BigInteger;
import java.util.Random;
public class TestRsa {
private BigInteger p, q;
private BigInteger n;
private BigInteger PhiN;
private BigInteger e, d;
public TestRsa() {
initialize();
}
public void initialize() {
int SIZE = 512;
/* Step 1: Select two large prime numbers. Say p and q. */
p = new BigInteger(SIZE, 15, new Random());
q = new BigInteger(SIZE, 15, new Random());
/* Step 2: Calculate n = p.q */
n = p.multiply(q);
/* Step 3: Calculate ?(n) = (p - 1).(q - 1) */
PhiN = p.subtract(BigInteger.valueOf(1));
PhiN = PhiN.multiply(q.subtract(BigInteger.valueOf(1)));
/* Step 4: Find e such that gcd(e, ?(n)) = 1 ; 1 < e < ?(n) */
do {
e = new BigInteger(2 * SIZE, new Random());
} while ((e.compareTo(PhiN) != 1)
|| (e.gcd(PhiN).compareTo(BigInteger.valueOf(1)) != 0));
/* Step 5: Calculate d such that e.d = 1 (mod ?(n)) */
d = e.modInverse(PhiN);
}
public BigInteger encrypt(BigInteger plaintext) {
return plaintext.modPow(e, n);
}
public BigInteger decrypt(BigInteger ciphertext) {
return ciphertext.modPow(d, n);
}
public static void main(String[] args) throws IOException {
TestRsa app = new TestRsa();
int plaintext;
System.out.println("Enter any character : ");
plaintext = System.in.read();
BigInteger bplaintext, bciphertext;
bplaintext = BigInteger.valueOf((long) plaintext);
bciphertext = app.encrypt(bplaintext);
System.out.println("Plaintext : " + bplaintext.toString());
System.out.println("Ciphertext : " + bciphertext.toString());
bplaintext = app.decrypt(bciphertext);
System.out.println("After Decryption Plaintext : "
+ bplaintext.toString());
}
}
最佳答案
我的RSA课程:
package com.infovale.cripto;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.InvalidKeyException;
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.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Arrays;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
public class RSA {
static String kPublic = "";
static String kPrivate = "";
public RSA()
{
}
public String Encrypt(String plain) throws NoSuchAlgorithmException,
NoSuchPaddingException, InvalidKeyException,
IllegalBlockSizeException, BadPaddingException {
String encrypted;
byte[] encryptedBytes;
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(1024);
KeyPair kp = kpg.genKeyPair();
PublicKey publicKey = kp.getPublic();
PrivateKey privateKey = kp.getPrivate();
byte[] publicKeyBytes = publicKey.getEncoded();
byte[] privateKeyBytes = privateKey.getEncoded();
kPublic = bytesToString(publicKeyBytes);
kPrivate = bytesToString(privateKeyBytes);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
encryptedBytes = cipher.doFinal(plain.getBytes());
encrypted = bytesToString(encryptedBytes);
return encrypted;
}
public String Decrypt(String result) throws NoSuchAlgorithmException,
NoSuchPaddingException, InvalidKeyException,
IllegalBlockSizeException, BadPaddingException {
byte[] decryptedBytes;
byte[] byteKeyPrivate = stringToBytes(kPrivate);
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey privateKey = null;
try {
privateKey = kf.generatePrivate(new PKCS8EncodedKeySpec(byteKeyPrivate));
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
String decrypted;
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
decryptedBytes = cipher.doFinal(stringToBytes(result));
decrypted = new String(decryptedBytes);
return decrypted;
}
public String bytesToString(byte[] b) {
byte[] b2 = new byte[b.length + 1];
b2[0] = 1;
System.arraycopy(b, 0, b2, 1, b.length);
return new BigInteger(b2).toString(36);
}
public byte[] stringToBytes(String s) {
byte[] b2 = new BigInteger(s, 36).toByteArray();
return Arrays.copyOfRange(b2, 1, b2.length);
}
}