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;
}
Related
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?
I am trying to encrypt and decrypt a message within java using RSA encryption. We have stored our keys as bytes in their own respective files, and load the contents of these files to be used as the keys in our encryption/ decryption methods. However, when I compile the code, I receive error:
javax.crypto.IllegalBlockSizeException: Data must be longer than 256
bytes.
Our generateKeys and encryption/ decryption methods read:
import java.security.*;
import java.security.spec.*;
import java.util.Base64;
import java.util.Scanner;
import java.io.*;
import java.nio.file.*;
import javax.crypto.Cipher;
public class Encryption {
static File filepath = new File("..\\..\\..\\");
public static void generateKeyPair() throws Exception {
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
generator.initialize(2048);
KeyPair pair = generator.generateKeyPair();
PublicKey publicKey = pair.getPublic();
PrivateKey privateKey = pair.getPrivate();
DataOutputStream dos = null;
try {
dos = new DataOutputStream(new FileOutputStream(filepath.getAbsolutePath()
+ "rsaPublicKey"));
dos.write(publicKey.getEncoded());
dos.flush();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
if (dos != null) {
try {
dos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
try {
dos = new DataOutputStream(new FileOutputStream(filepath.getAbsolutePath()
+ "rsaPrivateKey"));
dos.write(privateKey.getEncoded());
dos.flush();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
if (dos != null)
try {
dos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static KeyPair getKeyPair() throws Exception {
byte[] keyBytesPublic = Files.readAllBytes(Paths.get(filepath + "rsaPublicKey"));
byte[] keyBytesPrivate = Files.readAllBytes(Paths.get(filepath + "rsaPrivateKey"));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(keyBytesPublic);
PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(keyBytesPrivate);
PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);
KeyPair keys = new KeyPair(publicKey, privateKey);
return keys;
}
public static byte[] Encrypt (String plainText, PublicKey publicKey) throws Exception
{
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] cipherText = cipher.doFinal(plainText.getBytes());
return cipherText;
}
public static String Decrypt (byte[] cipherTextArray, PrivateKey privateKey) throws Exception
{
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedTextArray = cipher.doFinal(cipherTextArray);
return new String(decryptedTextArray);
}
}
We then call these methods, where we receive our error:
KeyPair pair = Encryption.getKeyPair();
PublicKey publicKey = pair.getPublic();
PrivateKey privateKey = pair.getPrivate();
// plugin.getLogger().info(chatMessage);
ids = chatMessage.substring(chatMessage.length() - 9, chatMessage.length() - 1);
plugin.getLogger().info(ids);
chatMessage = chatMessage.substring(0, chatMessage.length() - 10);
chatMessage = Encryption.Decrypt(chatMessage.getBytes(), privateKey);
server.broadcastMessage(chatMessage);
byte[] ctArray = Encryption.Encrypt("Sent message successfully.", publicKey);
encrypted_return = Base64.getEncoder().encodeToString(ctArray);
send(encrypted_return);
CipherText
i5SvmG2TbtZfkWdwJ5qeaYzvLlQknY3uMvZxSEwhBdRcXKHjgzrRk6XLDCEG9ZtZDGDA7iB3tFhLPMisfqGZvSSrcBfiV8b71+qzWVDNW9EedVShk6kaeEN6rw4UgVi6P5PvrDMn6pmYmLWCjtuFWrmboCvvYgI+FJurhlbsQESkA5oDYirjS8L0wnsQB/TnnQ5UPY2xfOBdY2MJpUSTyIjJPhI40GST8YWjXEMkJeDV/1zuKuK55RHCDF5AdTMEvgvvRnGhN2Fzh+rsDziHqVS9d8FmrtjdU445F6ki0d8DkaeFfrofptxGIncqfuukKSXpSp4cPLvM3LxtRvp+Aw==
Code to decrypt
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(2048);
KeyPair kp2 = kpg.generateKeyPair();
generatedPub = kp2.getPublic();
generatedPvt = kp2.getPrivate();
public String rsaDecrypt(String encrypted) {
try {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, generatedPvt);
byte[] original = cipher.doFinal(Base64.decodeBase64(encrypted.getBytes()));
return new String(original);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
Error
javax.crypto.BadPaddingException: error:04000089:RSA routines:OPENSSL_internal:PKCS_DECODING_ERROR
Also, if I try printing the private key as :
generatedPvt.toString()
I get the following :
OpenSSLRSAPrivateCrtKey{modulus=c7544bf521bbdd7db52dd28bd3c6f694214dc2356b905edd2730b631d11be9aea703692c2db690e6725da65737b5ec511c13668d1735bfbbc2519e0d33a67b41b289bae6ea71903af91e4f12c6e8660614ef12cd439293a0a38f564fd8f19a3e38f9e2defa269d0bcf0f53159bba1b4fd539ad934fb691e860113be53901de5a10d0c0e3ceaec3715841bc6e56b7738336e8df95a989b61175b06d70d349dcb4a031acf5b25647a1d77f6e6e11efc66e98bb321430f148a63c103a0a59e94b147a4fb49a9ecb0b23603a6ceed6e6e298650667cd61de71455bd4f95767444d89bcf485cc47a297b5306a60a14f77a3fbc19552c5fddfa5cfa2e68020e245ad91,publicExponent=10001}
While I was expecting the PKCS#8 formatted key to be printed. How do i get the key printed in the PKCS#8 format ?
And why am i getting the padding error as shown above ?
byte[] original = cipher.doFinal(encrypted.getBytes());
remove Base64.decodeBase64 from both encrypt and decrypt methods
if you want to convert key to string then use
String keyString= Base64.encodeBase64String(key.getEncoded());
RSA Implementation
public static void main(String[] args) {
try {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(2048);
KeyPair kp2 = kpg.generateKeyPair();
PublicKey publicKey = kp2.getPublic();
PrivateKey privateKey = kp2.getPrivate();
NewClass nc = new NewClass();
byte[] encrypt=nc.rsaEncrypt("hi",publicKey);
byte[] decrypt=nc.rsaDecrypt(encrypt,privateKey);
String decryptString = new String(decrypt);
System.out.println("decryptString = " + decryptString);
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(NewClass.class.getName()).log(Level.SEVERE, null, ex);
}
}
public byte[] rsaDecrypt(byte[] encrypted,PrivateKey privateKey) {
try {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] original = cipher.doFinal(encrypted);
return original;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public byte[] rsaEncrypt(String message,PublicKey publicKey) {
try {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] original = cipher.doFinal(message.getBytes());
return original;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
When encoding and decoding is done along with encrypt and decrypt the order must be
Encryption
cipher.doFinal(Base64.encodeBase64(message.getBytes()));
Decryption
Base64.decodeBase64(cipher.doFinal(cipher.getBytes()));
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
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.