-
-
Save Anass-ABEA/e2627b5df9abf23e006bcd5d390de205 to your computer and use it in GitHub Desktop.
import javax.crypto.Cipher; | |
import java.security.*; | |
import java.security.spec.PKCS8EncodedKeySpec; | |
import java.security.spec.X509EncodedKeySpec; | |
import java.util.Base64; | |
/** | |
* @author Anass AIT BEN EL ARBI | |
* <ul> | |
* <li>AES/CBC/NoPadding (128)</li> | |
* <li>AES/CBC/PKCS5Padding (128)</li> | |
* <li>AES/ECB/NoPadding (128)</li> | |
* <li>AES/ECB/PKCS5Padding (128)</li> | |
* <li>RSA/ECB/PKCS1Padding (1024, 2048)</li> | |
* <li>RSA/ECB/OAEPWithSHA-1AndMGF1Padding (1024, 2048)</li> | |
* <li>RSA/ECB/OAEPWithSHA-256AndMGF1Padding (1024, 2048)</li> | |
* </ul> | |
* <p> | |
* for more details @see <a href="https://docs.oracle.com/javase/7/docs/api/javax/crypto/Cipher.html">Java Ciphers</a> | |
*/ | |
public class RSA { | |
private PrivateKey privateKey; | |
private PublicKey publicKey; | |
private static final String PRIVATE_KEY_STRING = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJhBgzcXBm5A0srvFFu4FsBy+LLW+X0sH/9RvP40VIGOCusY0/CqA65YXWqyQE5jQCegBmnAeVYSvK+3PU4Y1fmr1uiquE6sZB5sl96T0ka+PKzPf4oKoAi6nwLUSenj5xTFjLsFGiuMXrCpMCPImf9JBVk89TJV43Xs3DSNKoj1AgMBAAECgYBsDysCgVv2ChnRH4eSZP/4zGCIBR0C4rs+6RM6U4eaf2ZuXqulBfUg2uRKIoKTX8ubk+6ZRZqYJSo3h9SBxgyuUrTehhOqmkMDo/oa9v7aUqAKw/uoaZKHlj+3p4L3EK0ZBpz8jjs/PXJc77Lk9ZKOUY+T0AW2Fz4syMaQOiETzQJBANF5q1lntAXN2TUWkzgir+H66HyyOpMu4meaSiktU8HWmKHa0tSB/v7LTfctnMjAbrcXywmb4ddixOgJLlAjEncCQQC6Enf3gfhEEgZTEz7WG9ev/M6hym4C+FhYKbDwk+PVLMVR7sBAtfPkiHVTVAqC082E1buZMzSKWHKAQzFL7o7zAkBye0VLOmLnnSWtXuYcktB+92qh46IhmEkCCA+py2zwDgEiy/3XSCh9Rc0ZXqNGD+0yQV2kpb3awc8NZR8bit9nAkBo4TgVnoCdfbtq4BIvBQqR++FMeJmBuxGwv+8n63QkGFQwVm6vCuAqFHBtQ5WZIGFbWk2fkKkwwaHogfcrYY/ZAkEAm5ibtJx/jZdPEF9VknswFTDJl9xjIfbwtUb6GDMc0KH7v+QTBW4GsHwt/gL+kGvLOLcEdLL5rau3IC7EQT0ZYg=="; | |
private static final String PUBLIC_KEY_STRING = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCYQYM3FwZuQNLK7xRbuBbAcviy1vl9LB//Ubz+NFSBjgrrGNPwqgOuWF1qskBOY0AnoAZpwHlWEryvtz1OGNX5q9boqrhOrGQebJfek9JGvjysz3+KCqAIup8C1Enp4+cUxYy7BRorjF6wqTAjyJn/SQVZPPUyVeN17Nw0jSqI9QIDAQAB"; | |
public void init(){ | |
try { | |
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA"); | |
generator.initialize(1024); | |
KeyPair pair = generator.generateKeyPair(); | |
privateKey = pair.getPrivate(); | |
publicKey = pair.getPublic(); | |
} catch (Exception ignored) { | |
} | |
} | |
public void initFromStrings(){ | |
try{ | |
X509EncodedKeySpec keySpecPublic = new X509EncodedKeySpec(decode(PUBLIC_KEY_STRING)); | |
PKCS8EncodedKeySpec keySpecPrivate = new PKCS8EncodedKeySpec(decode(PRIVATE_KEY_STRING)); | |
KeyFactory keyFactory = KeyFactory.getInstance("RSA"); | |
publicKey = keyFactory.generatePublic(keySpecPublic); | |
privateKey = keyFactory.generatePrivate(keySpecPrivate); | |
}catch (Exception ignored){} | |
} | |
public void printKeys(){ | |
System.err.println("Public key\n"+ encode(publicKey.getEncoded())); | |
System.err.println("Private key\n"+ encode(privateKey.getEncoded())); | |
} | |
public String encrypt(String message) throws Exception { | |
byte[] messageToBytes = message.getBytes(); | |
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); | |
cipher.init(Cipher.ENCRYPT_MODE, publicKey); | |
byte[] encryptedBytes = cipher.doFinal(messageToBytes); | |
return encode(encryptedBytes); | |
} | |
private static String encode(byte[] data) { | |
return Base64.getEncoder().encodeToString(data); | |
} | |
private static byte[] decode(String data) { | |
return Base64.getDecoder().decode(data); | |
} | |
public String decrypt(String encryptedMessage) throws Exception { | |
byte[] encryptedBytes = decode(encryptedMessage); | |
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); | |
cipher.init(Cipher.DECRYPT_MODE, privateKey); | |
byte[] decryptedMessage = cipher.doFinal(encryptedBytes); | |
return new String(decryptedMessage, "UTF8"); | |
} | |
public static void main(String[] args) { | |
RSA rsa = new RSA(); | |
rsa.initFromStrings(); | |
try{ | |
String encryptedMessage = rsa.encrypt("Hello World"); | |
String decryptedMessage = rsa.decrypt(encryptedMessage); | |
System.err.println("Encrypted:\n"+encryptedMessage); | |
System.err.println("Decrypted:\n"+decryptedMessage); | |
}catch (Exception ingored){} | |
} | |
} |
@VietDiepAnh Short answer is no.
if you try to encrypt the same text, you will get different cyphertexts each time due to the RSA padding scheme used (PKCS1Padding). It's done for security reasons to prevent building patterns that could reveal the original text or the key.
Edit: You might consider generating your own keys instead of using the keys I shared.
Thanks for your response, but When I use the public key I have, the generated ciphertext always different each time!
My target is to get same encrypted text every time for the same input and Public_key(base64) like you share!
Try below example.
private PrivateKey getBase64PrivateKey() throws DataEncryptionException {
StringBuilder pkcs8Lines = new StringBuilder();
try (BufferedReader rdr = new BufferedReader(new FileReader(base64PrivateKey))) {
String line;
while ((line = rdr.readLine()) != null) {
pkcs8Lines.append(line);
}
String pkcs8Pem = pkcs8Lines.toString();
pkcs8Pem = pkcs8Pem.replace("-----BEGIN PRIVATE KEY-----", "");
pkcs8Pem = pkcs8Pem.replace("-----END PRIVATE KEY-----", "");
pkcs8Pem = pkcs8Pem.replaceAll("\\s+","");
byte [] pkcs8EncodedBytes = Base64.getDecoder().decode(pkcs8Pem);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pkcs8EncodedBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePrivate(keySpec);
}catch (IOException | InvalidKeySpecException | NoSuchAlgorithmException e) {
throw new DataEncryptionException(e.getMessage());
}
}
private byte[] decryptByteArray(String encryptedMessage) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
Cipher decryptCipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
decryptCipher.init(Cipher.DECRYPT_MODE, getBase64PrivateKey());
return decryptCipher.doFinal(Base64.getDecoder().decode(encryptedMessage));
}
public String decrypt(String encryptedMessage) throws NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException {
LOGGER.info(() -> "Start decrypting data.");
return new String(decryptByteArray(encryptedMessage), StandardCharsets.UTF_8);
}
I keep running this code and keep getting the same error:
"Padding error in decryption"
Do you know why?
@manuelfdg , I have just tested it on an online debugger and it works check it out, or send me your code.
Does the encrypt always return same value with same input?