Encrypt with base64 rsa public key in Node.js - java

First of all, I'm a beginner programmer
I created a pair of keys(rsa) on the user's side(android). I intend to send the public key to the server for future operations as a base64 string, and with the public key I will encode the next data and send it to the user.I use the server side of the nodejs. Unfortunately, all the content written in The internet did not mention encrypt with the base64 public key or at least I did not see it. Can someone help me? Thank
this my java code:
public class GenKey {
private String stringPrivateKey;
private String stringPublicKey;
#RequiresApi(api = Build.VERSION_CODES.O)
public GenKey() throws NoSuchAlgorithmException {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(512,new SecureRandom());//1024 or 2048
KeyPair kp = kpg.generateKeyPair();
PublicKey publicKey = kp.getPublic();
PrivateKey privateKey = kp.getPrivate();
this.stringPublicKey = Base64.encodeToString(publicKey.getEncoded(), DEFAULT);
this.stringPrivateKey =Base64.encodeToString(privateKey.getEncoded(), DEFAULT);
}
public String getPublicKey(){
return stringPublicKey;
}
public String getPrivateKey(){
return stringPrivateKey;
}
}
and:
public class EncryptDecrypt {
public static String encrypt(String publicKey, String cleartext) throws Exception {
X509EncodedKeySpec ks = new X509EncodedKeySpec(Base64.decode(publicKey,DEFAULT));
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey pub = kf.generatePublic(ks);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pub);
byte[] encMsgBinary = cipher.doFinal(cleartext.getBytes());
return Base64.encodeToString(encMsgBinary, DEFAULT);
}
public static String decrypt(String privateKey, String ciphertext) throws Exception {
PKCS8EncodedKeySpec ks = new PKCS8EncodedKeySpec(Base64.decode(privateKey,DEFAULT));
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey pvt = kf.generatePrivate(ks);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, pvt);
byte [] encrypted = Base64.decode(ciphertext,DEFAULT);
return new String(cipher.doFinal(encrypted));
}
}

solved.use node-rsa;
var NodeRSA = require('node-rsa');
var key = new NodeRSA();
var public="-----BEGIN PUBLIC KEY-----\n"+publicKey+"\n"+"-----END PUBLIC KEY-----";
key.importKey(public,"pkcs8-public-pem");
var encrypted = key.encrypt(text, 'base64');
return encrypted;
and in java EncryptDecrypt class
Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding");
instead of
Cipher.getInstance("RSA");
see:
enter link description here

Related

How can I create a RSA Encrypter with a String Public Key

I have a System that generates a PublicKey, then encrypts a password, then they are both stored in a database.
PK Generator
public PublicKey GetPK() {
try {
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
generator.initialize(2048);
KeyPair pair = generator.generateKeyPair();
return pair.getPublic();
} catch(Exception e) {
return null;
}
}
Password Encryption
public static String EncryptPassword(PublicKey publicKey, String password) {
try {
Cipher encryptCipher = Cipher.getInstance("RSA");
encryptCipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] secretMessageBytes = password.getBytes(StandardCharsets.UTF_8);
byte[] encryptedMessageBytes = encryptCipher.doFinal(secretMessageBytes);
return Base64.getEncoder().encodeToString(encryptedMessageBytes);
} catch(Exception e) {
return null;
}
}
Then, what I try to make Login , I retrieve this Public key, encrypt my login form's password using this Public Key, and it Just don't give me the same encrypted password.
PuclicKey return
public PublicKey ReturnPK(String keyFromDatabase) throws InvalidKeySpecException, NoSuchAlgorithmException {
KeyFactory kf = KeyFactory.getInstance("RSA");
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(keyFromDatabase));
return kf.generatePublic(keySpec);
}
Compare Passwords
PublicKey pk = encryption.ReturnHash(GetUsers().getHashCode());
String encryptedPw = encryption.EncryptPassword(pk, pwd);
boolean loginState = encryptedPw.equals(dbPwd);
The var loginState always returns false. Can someone help me?

javax.crypto.BadPaddingException: Decryption error and also Message larger than modulus

Below I try to send message in multicast socket through group and to provide encryption:
Encrypt the data with the symmetric key
Encrypt the symmetric key with rsa
send the encrypted key and the data
Decrypt the encrypted symmetric key with rsa
decrypt the data with the symmetric key
But I am getting this error
javax.crypto.BadPaddingException: Decryption error at java.base/sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:378) at java.base/sun.security.rsa.RSAPadding.unpad(RSAPadding.java:290) at java.base/com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:366) at java.base/com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:392) at java.base/javax.crypto.Cipher.doFinal(Cipher.java:2208) at Security.RSADecryption(Symmetra.java:63) at ReadThread.run(Symmetra.java:202) at java.base/java.lang.Thread.run(Thread.java:835)
I think I did not understood encryption decryption properly.
See below for the code:
class Security
{
public static SecretKey createAESKey() throws Exception
{
KeyGenerator generator = KeyGenerator.getInstance("AES");
generator.init(128); // The AES key size in number of bits
SecretKey key = generator.generateKey();
return key;
}
public static KeyPair generateRSAkeyPair() throws Exception
{
//SecureRandom secureRandom = new SecureRandom();
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
//KeyGenerator keyGenerator = KeyGenerator.getInstance("RSA");
keyPairGenerator.initialize(4096);
KeyPair pair = keyPairGenerator.generateKeyPair();
return pair;
}
public static byte[] AESEncryption(String plaintext, SecretKey secKey) throws Exception
{
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE,secKey);
byte[] cipherText = cipher.doFinal(plaintext.getBytes());
return cipherText;
}
public static byte[] RSAEncryption(PublicKey publicKey, SecretKey key) throws Exception
{
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
//cipher.update(plaintext.getBytes());
byte [] encryptedKey = cipher.doFinal(key.getEncoded());
System.out.println(encryptedKey.length);
return encryptedKey;
}
public static byte[] RSADecryption(byte[] encryptedKey, PrivateKey privateKey) throws Exception
{
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte check[] = cipher.doFinal(encryptedKey);
return cipher.doFinal(encryptedKey);
}
public static String AESDecryption(byte[] decryptedKey, byte[] text) throws Exception
{
SecretKey originalKey = new SecretKeySpec(decryptedKey , 0, decryptedKey.length, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, originalKey);
byte[] plaintext = cipher.doFinal(text);
return new String(plaintext);
}
public static KeyPair generate() throws Exception
{
KeyPair keyPair = generateRSAkeyPair();
return keyPair;
}
}
public class TestDemo extends Security
{
public static void main(String args[])
{
KeyPair keyPair = generate();
SecretKey key = createAESKey();
byte[] cipherText = AESEncryption(message,key);
byte[] encryptedKey = RSAEncryption(keyPair.getPublic(), key);
DatagramPacket datagram = new
DatagramPacket(cipherText,cipherText.length,group,port); // It carries encrpyted message
// It carries symmetric key encrypted by RSA
DatagramPacket datagram2 = new
DatagramPacket(encryptedKey,encryptedKey.length,group,port);
socket.send(datagram);
socket.send(datagram2);
}
}
class ReadThread extends Security
{
KeyPair keyPair;
SecretKey key;
try
{
keyPair = generate();
key = createAESKey();
byte[] buffer = new byte[ReadThread.MAX_LEN];
DatagramPacket datagram = new DatagramPacket(buffer,buffer.length,group,port);
byte[] keyBuffer = new byte[512];
DatagramPacket datagram2 = new
DatagramPacket(keyBuffer,keyBuffer.length,group,port);
String message;
try
{
socket.receive(datagram);
socket.receive(datagram2);
byte[] decryptKey = RSADecryption(keyBuffer,keyPair.getPrivate());
String decryptText = AESDecryption(decryptKey, buffer);
message = decryptText;
if(!message.startsWith(Symmetra.name))
System.out.println(message);
}
catch(IOException e)
{
System.out.println("Socket closed!");
}
}
}

RSA Bad Padding Exception

I am trying to RSA encrypt data on Android and send it to server(spring).
getting BadPaddingException :
Approach:
server send public key in a string, which i convert to PublicKey Object and send data from App after encryption as a string.
server has a private key string , which is converted to PublicKey object and then data is decrypted.
Any Help would be much appreciated.
generation of key :
public static KeyPair generateKeyPairRSA() {
try {
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(1024, random);
KeyPair keyPair = keyGen.generateKeyPair();
return keyPair;
} catch (Exception e) {
Log.d(TAG,e.getLocalizedMessage());
}
return null;
}
public byte[] RSAEncrypt(final String plain, PublicKey publicKey) throws Exception {
Cipher cipher = Cipher.getInstance(ALGO_RSA);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptedBytes = cipher.doFinal(plain.getBytes());
return encryptedBytes;
}
public static PublicKey loadPublicKey1(String stored) throws Exception{
byte[] data = Base64.decode(stored.getBytes());
X509EncodedKeySpec spec = new X509EncodedKeySpec(data);
KeyFactory fact = KeyFactory.getInstance(ALGO_RSA);
return fact.generatePublic(spec);
}
Server Methods :
public byte[] decryptRSA(String inputData) throws Exception {
byte[] inputBytes = Base64.decodeBase64(inputData);
PrivateKey key = loadPrivateKey(getPrivateKey());
Cipher cipher1 = Cipher.getInstance("RSA");
cipher1.init(Cipher.DECRYPT_MODE, key);
return cipher1.doFinal(inputBytes);
}
private PrivateKey loadPrivateKey(String key64) throws Exception {
byte[] pkcs8EncodedBytes = Base64.decodeBase64(key64);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pkcs8EncodedBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePrivate(keySpec);
}
Got it Working.
So diffrent libs have differenet implementation of Cipher.
so while calling
Cipher.getInstance("RSA/ECB/PKCS1Padding");
Explicitly mention encryption mode and padding.
Hope it helps somebody.

In Java, how do I decrypt using the private key from an X509 certificate (public/private key pair) inside a JKS keystore?

I created a KeyStore using KeyStore Explorer with a public/private key pair inside it of type RSA, 4096 bytes, and PKCS#8 formatting.
I get an error when my code runs and hits the cipher.init() method :
"Key for algorithm RSA not suitable for symmetric encryption."
This doesn't really make sense to me because I'm using asymmetric key encryption/decryption. I'm not sure where to go from here or what I'm doing wrong.
Here is what I have:
public TransactionData processData(TransactionData data) throws BTHException {
String keystoreFilePath = manager.getStringValue(KeyStoreFilePath);
String keystorePassword = manager.getStringValue(KeyStoreFilePassword);
String privateKeyPassword = manager.getStringValue(KeyStorePrivateKeyPassword);
String certificateAlias = manager.getStringValue(CertificateAlias);
org.apache.xml.security.Init.init();
try {
InputStream in = data.getDataStream();
byte[] dataBytes = DataUtil.readBytes(in);
String encryptedDataStr = new String(dataBytes);
PrivateKey privateKey = getPrivateKeyFromKeyStore(keystoreFilePath, keystorePassword, certificateAlias, privateKeyPassword);
decrypt(
encryptedDataStr,
privateKey
);
}catch(Exception e){
throw new BTHException(e.getMessage());
}
return data;
}
private PrivateKey getPrivateKeyFromKeyStore(String keyStoreFilePath, String keyStorePassword, String privateKeyCertAlias, String privateKeyPassword) throws BTHException {
PrivateKey privateKey = null;
try {
KeyStore keystore = KeyStore.getInstance("JKS");
BASE64Encoder encoder = new BASE64Encoder();
keystore.load(new FileInputStream(keyStoreFilePath), keyStorePassword.toCharArray());
Key key=keystore.getKey(privateKeyCertAlias,keyStorePassword.toCharArray());
if(key instanceof PrivateKey) {
Certificate cert=keystore.getCertificate(privateKeyCertAlias);
PublicKey publicKey=cert.getPublicKey();
KeyPair keyPair = new KeyPair(publicKey,(PrivateKey)key);
privateKey = keyPair.getPrivate();
}
//privateKeyEncoded = encoder.encode(privateKey.getEncoded());
} catch (Exception e) {
throw new BTHException(e.getMessage());
}
return privateKey;
}
private String decrypt(String cipherText, PrivateKey privateKey) throws IOException, GeneralSecurityException, BTHException {
String decryptedValue = null;
try {
// 1. Get the cipher ready to start doing the AES transformation
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
// 2. Start the decryption process
// THIS IS WHERE IT FAILS
cipher.init(Cipher.DECRYPT_MODE, privateKey);
// 3. Finish the decryption process
decryptedValue = new String(cipher.doFinal(Base64.decodeBase64(cipherText)), "UTF-8");
} catch (Exception e) {
throw new BTHException(e.getMessage());
}
return decryptedValue;
}
Any help would be great. Thanks in advance!
You are trying to initialize your cipher as AES/CBC/PKCS5Padding which is an symmetric encryption and that is where the exception originates.
You should use the Cipher like that:
// 1. Get the cipher ready to start doing the RSA transformation
Cipher cipher = Cipher.getInstance("RSA");
// 2. Start the decryption process
cipher.init(Cipher.DECRYPT_MODE, privateKey);
Here you can find a good example for RSA-Encryption and Decryption.

read public key invalid key format java

I have code:
public PublicKey read_public_key(String path)
throws IOException, NoSuchAlgorithmException,
InvalidKeySpecException {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
FileInputStream pubKeyStream = new FileInputStream(path);
byte[] pubKeyBytes = new byte[(int)path.length()];
pubKeyStream.read(pubKeyBytes);
pubKeyStream.close();
X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(pubKeyBytes);
PublicKey pubKey = keyFactory.generatePublic(pubKeySpec);
return pubKey;
}
But I get invalid key format How do I get public key from .pub file? Later I need to:
private static byte[] encrypt(String text, PublicKey key) {
byte[] cipherText = null;
try {
// get an RSA cipher object and print the provider
final Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding");
// encrypt the plain text using the public key
cipher.init(Cipher.ENCRYPT_MODE, key);
cipherText = cipher.doFinal(text.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
return cipherText;
}

Categories

Resources