Im Trying to do my homework to create a class called Password that implements the Encryptable interface.
Im trying using RSA Algorythm.
I use some RSA code references from the Google and resulting my code below.
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Key;
import java.util.Arrays;
import javax.crypto.Cipher;
import java.util.Scanner;
public class Password
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
String password = sc.nextLine();
KeyPair keyPair = RSAKeyPair.keyPairRSA();
Key publicKey = keyPair.getPublic();
Key privateKey = keyPair.getPrivate();
System.out.println("Original: " + password);
byte[] encrypted = RSAEncryptDecrypt.encrypt(password, privateKey);
System.out.println("Encrypted: " + new String(encrypted));
byte[] decrypted = RSAEncryptDecrypt.decrypt(encrypted, publicKey);
System.out.println("Decrypted: " + new String(decrypted));
}
}
final class RSAConstants {
private RSAConstants() {
}
public static final String ALGORITHM = "RSA";
public static final int ALGORITHM_BITS = 2048;
}
class RSAKeyPair {
public static KeyPair keyPairRSA() {
KeyPairGenerator generator = null;
try {
generator = KeyPairGenerator.getInstance(RSAConstants.ALGORITHM);
} catch (Exception e) {
e.printStackTrace();
}
if (generator != null) {
generator.initialize(RSAConstants.ALGORITHM_BITS);
KeyPair keyPair = generator.genKeyPair();
return keyPair;
}
return null;
}
}
class RSAEncryptDecrypt {
public static byte[] encrypt(String original, Key privateKey) {
if (original != null && privateKey != null) {
byte[] bs = original.getBytes();
byte[] encData = convert(bs, privateKey, Cipher.ENCRYPT_MODE);
return encData;
}
return null;
}
public static byte[] decrypt(byte[] encrypted, Key publicKey) {
if (encrypted != null && publicKey != null) {
byte[] decData = convert(encrypted, publicKey, Cipher.DECRYPT_MODE);
return decData;
}
return null;
}
private static byte[] convert(byte[] data, Key key, int mode) {
try {
Cipher cipher = Cipher.getInstance(RSAConstants.ALGORITHM);
cipher.init(mode, key);
byte[] newData = cipher.doFinal(data);
return newData;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
My Input is:
InterstellarGalactica
All goes smooth except for the result of Encrypted Password Resulting below
Original: InterstellarGalactica
Encrypted: Sªë/H?ù,X?U4??A???ìñáQ
÷? *?7*??d?'å?Ñ¡w °??? Pè???«{?D÷??cB???'É »???qªîÉDë??~hb??z8?çÿ?hí?{mè?{*îèGê??WÅ{x??ï.5¼?úü;e??G?-F?shèn?FI
áh`UƒIàB!?åäô+D<&"?)?????ß!??3ä?¬???â???<?¬Ü?{ @ó12B?òt?ƒòÆr²Ä·oHQ?ë?«ú?°?î??Äy?:X^<?
&:ryb\?¼
Decrypted: InterstellarGalactica
Why do it is became a meaningless character?
Is there anything wrong with my code?
Can you explain how to do it in proper way(if there is)?
Thanks in advance.
You are using RSA in the wrong way:
In RSA you use the public key for encryption and the private key for decryption.
You however use the private key for encryption and the public key for decryption:
byte[] encrypted = RSAEncryptDecrypt.encrypt(password, privateKey);
byte[] decrypted = RSAEncryptDecrypt.decrypt(encrypted, publicKey);
Additionally please never convert a byte[]
that contains binary data to String. If you want to print binary data convert it for example to a hexadecimal or base64 String instead. Or if you want to print it as a number use BigInteger
.
// output Base64 encoded
System.out.println(java.util.Base64.getEncoder().encode(encrypted));
// out hexadecimal (uses Apache commons codec library
System.out.println(org.apache.commons.codec.binary.Hex.encodeHexString(encrypted));
// out hexadecimal without external library)
System.out.println(new java.math.BigInteger(1, encrypted).toString(16))
// Output as large number (useful for manual RSA calculations)
System.out.println(new java.math.BigInteger(1, encrypted));