I want to encrypt/ decrypt with AES, with shared passwod, my code same as here.
the linked code works fine, but there is no shared passworn in it.
how can I add a shared password to the following implementation?
I need something like
String shared="xxx..";//some password with 16 digits length
Is it possible?
and adding this shared password to the encryption.
It is very important that the key used for AES encryption is not easy to guess so in a lot of implementations the keys are generated randomly. The key itself is a byte array of 16 (128 bit), 24 (192 bit) or 32 (256 bit) byte length and a byte array is not usuable as source for a shared password.
The solution is to encode the byte array into a Base64-encoded string and pass this string to the recepient on a secure way. The recepient decodes the string back to a byte array and further via the SecretKeySpec to a secret key.
The small example shows the way to securly generate a random password with different lengths (the example uses only the 128 bit keylength, encode it and decode it back to a secret key - the orginal SecretKey k is compared to the regenerated SecretKex kReceived.
Just a last notice but it is a security warning: Your encryption method is using the AES ECB mode that is unsecure - please do not use this mode in production (mode is defined here: AES/ECB/PKCS5Padding).
Result:
https://stackoverflow.com/questions/62782129/encrypt-files-with-aes-with-shared-password
sharedKey: UT7PPJwX2fnYTazSOZAhxg==
keySpecReceived equals secretKey: true
Code:
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;
public class Main {
public static void main(String[] args) throws NoSuchAlgorithmException {
System.out.println("https://stackoverflow.com/questions/62782129/encrypt-files-with-aes-with-shared-password");
// random key creation taken from https://stackoverflow.com/a/41414233/9114020
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
SecureRandom secureRandom = new SecureRandom();
int keyBitSize = 128; // aes keylength can be 128, 192 or 256 bit
keyGenerator.init(keyBitSize, secureRandom);
SecretKey k = keyGenerator.generateKey();
// encode the key and then base64-encoding
String sharedKey = Base64.getEncoder().encodeToString(k.getEncoded());
System.out.println("sharedKey: " + sharedKey);
// share this key with another party on a secure way
String sharedKeyReceived = sharedKey; // simulates the receiving
byte[] sharedKeyByteReceived = Base64.getDecoder().decode(sharedKeyReceived);
SecretKeySpec kReceived = new SecretKeySpec(sharedKeyByteReceived, "AES");
System.out.println("keySpecReceived equals secretKey: " + kReceived.equals(k));
}
}
Related
I have a situation where I have to store the encrypted from of a text in an excel sheet and my java code should read that encrypted text from a excel sheet and convert it back to original text and hit the server with original plain text.
I'm trying to achieve this with AES encryption/decryption logic but I'm not able to achieve it as every time I convert the plain text into encrypted format for it to be stored in the excel sheet it results in a different encrypted string each time so I'm not able to decrypt it back to original, what I want is for a same static string/text my AES encrypted text should also be static.
I know even if my encrypted string is dynamic I can convert it back to decrypted format but for my case what I want is my encrypted text should also remain static.
How can I achieve this?
Ex. If my plain text is "This is a question" my encrypted string is different each time like below
Enter
This is a question
Encrypted Data : mFsue8JGwLcJQTiBzM0HLVvdDXKPNGsG/O7N60joH+Ozgg==
Decrypted Data : This is a question
Enter
This is a question
Encrypted Data : FdBz3cGS4NphK14Fw8Me4daM4lVzdrK47WUMSRiUVe+juQ==
Decrypted Data : This is a question
See the encrypted data's are different each time. I want that to be static
The classes which I'm using are as below (please note these are not my exact classes but they implement the same logic which I have used. These example classes may have some non used variables and methods, I have mentioned just for reference)
Method.java
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
public class Method {
private static SecretKey key;
private final int KEY_SIZE = 128;
private final int DATA_LENGTH = 128;
private Cipher encryptionCipher;
/*
* public void init() throws Exception { KeyGenerator keyGenerator =
* KeyGenerator.getInstance("AES"); keyGenerator.init(KEY_SIZE); key =
* keyGenerator.generateKey();
*
*
* }
*/
// String to Key
public static void getKeyFromPassword(String toEnc, String salt) throws
NoSuchAlgorithmException, InvalidKeySpecException { SecretKeyFactory factory
= SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); KeySpec spec = new
PBEKeySpec(toEnc.toCharArray(), salt.getBytes(), 65536, 128); SecretKey
originalKey = new SecretKeySpec(factory.generateSecret(spec).getEncoded(),"AES");
key= originalKey; }
/*
* public static void convertStringToSecretKeyto(String string) {
*
*
* byte[] bytesEncoded = Base64.getEncoder().encode(string.getBytes()); byte[]
* decodedKey = Base64.getDecoder().decode(string); key = new
* SecretKeySpec(decodedKey, 0, decodedKey.length, "AES");
* System.out.println(bytesEncoded); System.out.println(decodedKey);
*
* }
*/
public String encrypt(String data) throws Exception {
byte[] dataInBytes = data.getBytes();
encryptionCipher = Cipher.getInstance("AES/GCM/NoPadding");
encryptionCipher.init(Cipher.ENCRYPT_MODE, key);
byte[] encryptedBytes = encryptionCipher.doFinal(dataInBytes);
return encode(encryptedBytes);
}
public String decrypt(String encryptedData) throws Exception {
byte[] dataInBytes = decode(encryptedData);
Cipher decryptionCipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec spec = new GCMParameterSpec(DATA_LENGTH,
encryptionCipher.getIV());
decryptionCipher.init(Cipher.DECRYPT_MODE, key, spec);
byte[] decryptedBytes = decryptionCipher.doFinal(dataInBytes);
return new String(decryptedBytes);
}
private String encode(byte[] data) {
return Base64.getEncoder().encodeToString(data);
}
private byte[] decode(String data) {
return Base64.getDecoder().decode(data);
}
}
Main.class
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import java.util.Base64;
import java.util.Scanner;
public class Cypher {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
Method aes_encryption = new Method();
// aes_encryption.init();
Method.getKeyFromPassword("Texty text","Salty salt");
System.out.println("Enter");
Scanner sc= new Scanner(System.in);
String s= sc.nextLine();
String encryptedData = aes_encryption.encrypt(s);
String decryptedData = aes_encryption.decrypt(encryptedData);
System.out.println("Encrypted Data : " + encryptedData);
System.out.println("Decrypted Data : " + decryptedData);
} catch (Exception ignored) {
}
}
}
This is not really an implementation issue; your issue is with the used encryption scheme.
The nonce or IV are used to randomize your ciphertext. This gives you an important property: identical plaintext will encrypt to randomized ciphertext. This is required for a cipher to be secure, as you could otherwise identify identical plaintext messages.
Now you could just fix the IV or nonce, but that means that you will leak information early: if the first blocks of plaintext are identical then those blocks will result in identical ciphertext. Instead you can use an encryption scheme where each of the ciphertext bits depend on all of the plaintext bits.
There are several schemes that offer this kind of property:
biIGE mode: the bi-directional infinite garble extension mode is an encryption mode that runs both forward and then backwards. It is an odd mode that isn't used or implemented much;
FPE modes: format preserving encryption can be used to encrypt X plaintext bits into exactly X ciphertext bits, it is mainly used for smaller plaintext messages such as credit cards (so that there aren't any additional storage requirements for encrypted credit card numbers);
AES-SIV mode: synthetic IV mode is probably the best option, it can encrypt large(r) messages, and offers authenticity as well as the MAC / authentication tag doubles as IV. It has the drawback that it does require additional room for the synthetic IV / authentication tag. It is also a two-pass mode (all plaintext bytes are visited twice), which means that it won't be as performant as other generic modes.
There is AES-GCM-SIV for a performant option of the latter.
Of course, as indicated by others, you really want to make sure that you need this kind of functionality: not having messages encrypt to the same ciphertext is a rather fundamental security property of a cipher.
Thank you for taking you time to assist me with this!
THIS POST HAS BEEN EDITED FOR LESS INFORMATION SEE THE EDITED PART
Well I have spend ours of research on this matter and I ended up with a working piece of code..
But Encryption is not a place to make mistakes, and I wanted to ask if my code is actualy secure! It's really important for me because I want to implement it to a program so my code is...
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;
public class EncryptFile{
private static final String FILE_IN = "./EncryptFile.java";
private static final String FILE_ENCR = "./EncryptFile_encr.java";
private static final String FILE_DECR = "./EncryptFile_decr.java";
public static void main(String []args){
try
{
Encryption("passwordisnottheactual", Files.readAllBytes(Paths.get(FILE_IN)));
Decryption("passwordisnottheactual");
}catch(Exception e){
System.out.println(e.getMessage());
}
}
private static void Encryption(String Key, byte[] byteArray) throws Exception
{
// Decode the base64 encoded Key
byte[] decodedKey = Base64.getDecoder().decode(Key);
// Rebuild the key using SecretKeySpec
SecretKey secretKey = new SecretKeySpec(decodedKey, 0, decodedKey.length, "AES");
// Cipher gets AES Algorithm instance
Cipher AesCipher = Cipher.getInstance("AES");
//Initialize AesCipher with Encryption Mode, Our Key and A ?SecureRandom?
AesCipher.init(Cipher.ENCRYPT_MODE, secretKey, new SecureRandom());
byte[] byteCipherText = AesCipher.doFinal(byteArray);
//Write Bytes To File
Files.write(Paths.get(FILE_ENCR), byteCipherText);
}
private static void Decryption(String Key) throws Exception
{
//Ddecode the base64 encoded string
byte[] decodedKey = Base64.getDecoder().decode(Key);
//Rebuild key using SecretKeySpec
SecretKey secretKey = new SecretKeySpec(decodedKey, 0, decodedKey.length, "AES");
//Read All The Bytes From The File
byte[] cipherText = Files.readAllBytes(Paths.get(FILE_ENCR));
//Cipher gets AES Algorithm Instance
Cipher AesCipher = Cipher.getInstance("AES");
//Initialize it in Decrypt mode, with our Key, and a ?SecureRandom?
AesCipher.init(Cipher.DECRYPT_MODE, secretKey, new SecureRandom());
byte[] bytePlainText = AesCipher.doFinal(cipherText);
Files.write(Paths.get(FILE_DECR), bytePlainText);
}
}
EDIT
Possible duplicate of Simple Java AES encrypt/decrypt example – JFPicard
Well it could be but these answers Use IVParameterSpec and I wanted to know if
this line of code is actually secure or if it is bad practice:
AesCipher.init(Cipher.DECRYPT_MODE, secretKey, new SecureRandom());
because I use a new SecureRandom() every time,
and I haven't seen anyone use a SecureRandom object like this.
Encryption key
The password is passes as a string but the Encryption function Base64 decoded it, that is a coding error.
When a password is used the encryption key should be derived from it with the PBKDF2 (aka Rfc2898DeriveBytes) function.
When using key derivation the salt and iteration count needs to be available for decryption, often they are provided in a prefix to the encrypted data.
Encryption mode
No encryption mode is supplied.
Use CBC mode with a random IV.
Just prefix the encrypted data with the IV for use on decryption.
Padding
AES is a block cipher and as such requires the input data size to be a multiple of the block size.
Specify PKCS#7 (née PKCS#5) padding, it will add padding on encryption and remove it on decryption.
On decryption do not return "padding" errors, they can provide a "Padding Oracle" attack.
Explicit
Specify all encryption parameters and sizes.
Do not rely on implementation defaults.
Encryption authentication
Consider if there is a need to know if the data is decrypted correctly.
Versioning
Add a version indicator so that if changes are necessary later there is an compatibility path.
Or consider using RNCryptor which handles all this and more.
Update: (thx Andy for the comment)
If GCM mode is available and interoperability across platforms and libraries is not an issue GCM is arguably a better encryption mode. GCM has authentication and padding build-in making it more robust and an easier secure solution.
Im having trouble with my attempt to create a small programme using hybrid encryption with AES and RSA. It works just fine using only symmetric encryption AES which i have tried, but when i try to implement RSA to wrap the AES encrypted message and key i just cant get it to work.
I have understood that a programme like this can be done using outputstreams or cipherstreams but I´d like to solve it this way if it is possible. In other words id like a user to enter any string into the JOptionInputDialog and get it encrypted with AES key and then the AES key encrpyted with RSA public key and then decrypted with a private RSA key.
I want the answer to display in the same JOptionPane window. In example :
The encrypted text : jfjfjh
The decrypted text : Hello
I have issues right now understanding how to get that string decrypted with the private RSA key. I dont know what i am missing or doing wrong. From any examples ive been googling for the past week and a half i think it looks fine. I must be missing something that is right infront of my eyes but i cant see it since i sit up for too many hours trying to find a different approach ( i think ive changed it a million times but i cant show you all my approaches so this is the one i share with you. Id be really thankful for any kind of help. So here is my code: (Hope you can understand as some words are in my language)
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.swing.JOptionPane;
/**
*
* #author Patricia
*/
public class EncryptionDecryption {
/**
* #param args the command line arguments
* #throws java.lang.Exception
*/
public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
//Creating assymmetric keys RSA ( A public Key and Private Key )
KeyPairGenerator gen2 = KeyPairGenerator.getInstance("RSA");
gen2.initialize(1024);
KeyPair keyPair = gen2.genKeyPair();
PrivateKey privatnyckel = keyPair.getPrivate();
PublicKey publiknyckel = keyPair.getPublic();
//Create assymmetric key AES //Create key generator
KeyGenerator gen = KeyGenerator.getInstance("AES"); //Returns keygenerator object that generates key for specified algorithm in this case AES
SecureRandom random = new SecureRandom();
gen.init(random);
// create a key
SecretKey AES = gen.generateKey();
//get the raw key bytes
byte[] symmetriskNyckel =AES.getEncoded(); //Returns copy of the key bytes
//Create cipher based upon AES, encrypt the message with AES key
Cipher cipher = Cipher.getInstance("AES");
//Initialize cipher with secret key AES
cipher.init(Cipher.ENCRYPT_MODE, AES);
// get the text to encrypt with AES key
String inputText1 = JOptionPane.showInputDialog(" Enter the secret message");
//Encrypt the plaintext message you wanna send with the symmetric key AES;
byte[] kryptera = cipher.doFinal(inputText1.getBytes());
//encrypt AES key with RSA
Cipher pipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
pipher.init(Cipher.WRAP_MODE, publiknyckel);
byte[] krypteradAESNyckel = cipher.wrap(AES);
JOptionPane.showMessageDialog(null, "AES key encrypted with RSA public key " + krypteradAESNyckel);
// re-initialise the cipher to be in decrypt mode
Cipher flipher = Cipher.getInstance("RSA");
flipher.init(Cipher.UNWRAP_MODE, privatnyckel );
// decrypt message
byte [] dekryptera = flipher.unwrap(kryptera);
JOptionPane.showMessageDialog
(null, "AES symmetrisk nyckel " +symmetriskNyckel );
// and display the results //
JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
"Texten krypterad " + new String(kryptera) + "\n"
+ "Text dekrypterat: " + new String(dekryptera));
JOptionPane.showMessageDialog(null, "\n RSA assymmetrisk privat nyckel " + privatnyckel
+ "RSA assymmetrisk publik nyckel" + publiknyckel);
// end example
System.exit(0);
}
}
I think your variable names and comments are fine to start with. When working with something new, write notes to yourself in the code. You can come back later once it works and refactor with rich, meaningful names, and trim the comments for clarity, so that they speak to you six months or a year from now to remind you of what you were thinking of at the time that you wrote this. (And I think Swedish names are just as good as English.)
As JB Nizet points out, you are unwrapping kryptera when you should be unwrapping the symmetric key contained in krypteradAESNyckel. Next, you would decrypt kryptera with the recovered symmetric key. (Your code justs outputs the earlier symmetriskNyckel without having actually unwrapped it freshly from krypteradAESNyckel.)
I also notice that in one case you
Cipher.getInstance("RSA/ECB/PKCS1Padding");
but later you
Cipher.getInstance("RSA");
I would make them consistent, both "RSA/ECB/PKCS1Padding". This attention to detail is just as important as clear variable names and meaningful comments.
I have written a small application to encrypt and decrypt Strings using AES. Here is the code:
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
public class AesEncryptionTest {
static IvParameterSpec initialisationVector = generateInitialisationVector();
static SecretKey encryptionKey = generateKey();
static String plainText = "test text 123\0\0\0";
public static void main(String [] args) {
try {
System.out.println("Initial Plain Text = " + plainText);
byte[] encryptedText = encrypt(plainText, encryptionKey);
System.out.println("Encrypted Text = " + encryptedText);
String decryptedText = decrypt(encryptedText, encryptionKey);
System.out.println("Decrypted Text = " + decryptedText);
} catch (Exception e) {
e.printStackTrace();
}
}
public static byte[] encrypt(String plainText, SecretKey encryptionKey) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding", "SunJCE");
cipher.init(Cipher.ENCRYPT_MODE, encryptionKey, initialisationVector);
return cipher.doFinal(plainText.getBytes("UTF-8"));
}
public static String decrypt(byte[] encryptedText, SecretKey encryptionKey) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding", "SunJCE");
cipher.init(Cipher.DECRYPT_MODE, encryptionKey, initialisationVector);
return new String(cipher.doFinal(encryptedText),"UTF-8");
}
public static SecretKey generateKey() {
SecretKey secretKey = null;
try {
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(128);
secretKey = keyGenerator.generateKey();
} catch (NoSuchAlgorithmException ex) {
// Whine a little
}
return secretKey;
}
public static IvParameterSpec generateInitialisationVector() {
byte[] initVector = new byte[16];
SecureRandom secureRandom = new SecureRandom();
secureRandom.nextBytes(initVector);
return new IvParameterSpec(initVector);
}
}
Output:
Initial Plain Text = test text 123
Encrypted Text = [B#407dcb32
Decrypted Text = test text 123
My main areas of concern are around encrypting into a byte array and decrypting back to a String. I know that this can introduce unexpected behaviour and loss of data. While this has not been observed in my testing, could anyone suggest any changes that would help combat this? I think I have this covered by ensuring UTF-8 is used both ways.
If anyone see's any other red flags with my code and how I have done this, I'm open to criticism/suggestions.
Many thanks!
You're calling toString() on a byte[] which is never a good idea. Basically it's not giving you any useful information.
If you want to convert arbitrary binary data into a string, I'd suggest using hex or base64, both of which are covered elsewhere. There's no indication that you've actually lost any information here in the encryption/decryption - the problem is your display of the encrypted data. So long as you don't try to treat that as simple encoded text data (because it isn't) you should be fine. In particular, your code is already specifying UTF-8 as the conversion from the original text to unencrypted binary data, and vice versa - so that's safe.
If you don't need to convert the byte array to a string, it's simplest to avoid doing so in the first place. (For example, you could write it to a file still in the binary form very simply, then load it back into a byte array later.)
You asked for other red flags, so I'll give you a few pointers regarding the crypto:
Generally you don't have to provide the provider name when you use an algorithm name. Specifying the provider makes your code less portable.
It is better to use a standardized padding mode such as "/PKCS5Padding" (identical to PKCS#7 padding in Java). If you want to use the current padding mode you can configure the Bouncy Castle provider and specify "/ZeroBytePadding". This padding mode does not work correctly for plaintext that ends with zero valued bytes.
You store the IV in the same class variable as the key. I know this is just test code, but normally the IV need to be send or established at both sides. The most common way to use the same key at both sides is to prefix the IV to the ciphertext.
The size of the IV depends on the cipher. It is always 16 for AES, but you may want to make the IV size configurable or use the Cipher.getBlockSize() method.
Use GCM mode (available since 1.8) encryption if you also want authenticity/integrity and protection against padding oracle attacks.
You should use a fresh, random IV for each encrypt, instead of generating an IV just once.
the way to make sure the conversion is without loss is to use the same Charset when converting back and forth as you do.
Creating a string of the encrypted data is however not safe for further use; it can contain any and all sequences of bytes and might not fit into whatever Charset you originally used (you're not making this error, just pointing it out).
You're also printing the hashcode of the byte[] mid way in the code, not the individual bytes.
I used Bouncy Castle Crypto APIs to decrypt a cipher text, and verify the signed message.
The signed message:
signedMessageOther: D0F39F8C8495CA83D2F24536083CCB280CD3A54B
The message decrypted:
01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFF003021300906052B0E03021A05000414D0F39F8C8495CA83D2F2453608
3CCB280CD3A54B
Only the last 20 bytes match the signedMessageOther.
Why?
Here is something about the key:
Algorithm: RSA
Format: X.509
Key Length: 162
The key is 162 bytes -1024 bi, so it is a vaild key.
Here is the code:
import java.security.PublicKey;
import java.security.Security;
import javax.crypto.Cipher;
public class DecyrptTest {
public static void main (String[] args) throws Exception {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
//msg is some secret msg ,i have deleted.
String msg = "";
byte[] signedMsgBytes = SHA1.sign(msg);
String signedMessageOther=StringTools.bytesToHex(signedMsgBytes);
System.out.println("signedMessageOther: "+signedMessageOther);
String ct="1386cfed01490b9026903722324f80f8a56cc38169b46e15154ce9e7168ff589282855002e195a0c1a96d5fe540a7fa97b01ae24f365f39302e0c1186ee9308d6b94526741f7093dc2678c713bb2b1a8a6942decb35b16725353da523417cb835cea903485b19b63c2c444c8bc6c865ea78c749f10ca70b266f6078192f5c76c";
Cipher cipher = Cipher.getInstance("RSA", "BC");
PublicKey pubKey = KeyUtil.getPubKeyFromFile("res/key.pub");
System.out.println("Algorithm: "+pubKey.getAlgorithm());
System.out.println("Format: "+pubKey.getFormat());
System.out.println("Key Length: "+pubKey.getEncoded().length);
cipher.init(Cipher.DECRYPT_MODE, pubKey);
byte[] ctBytes=StringTools.hexStringToByteArray(ct);
System.out.println(ctBytes.length);
byte[] cipherText2 = cipher.doFinal(ctBytes);
System.out.println("cipher: " + StringTools.bytesToHex(cipherText2));
}
}
You are are trying to drive to work with an internal combustion engine. You need a car.
RSA is a primitive operation that can be pieced with other things to make a useful encryption system. You can't just use it by itself to do the whole job.
I'm not sure if that's really saying the key is 162 bits, but if so, that's a completely useless RSA key size. An RSA key has to be at least 384 bits to be of any use at all. Also, RSA can't sign or encrypt data larger than the key. 162 bits is about 20 bytes. Sound familiar?
You can't use an engine to drive to work. You need a car. RSA is an engine.