Converting Secret Key into a String and Vice Versa

Converting Secret Key into a String and Vice Versa

You can convert the SecretKey to a byte array (byte[]), then Base64 encode that to a String. To convert back to a SecretKey, Base64 decode the String and use it in a SecretKeySpec to rebuild your original SecretKey.

For Java 8

SecretKey to String:

// create new key
SecretKey secretKey = KeyGenerator.getInstance("AES").generateKey();
// get base64 encoded version of the key
String encodedKey = Base64.getEncoder().encodeToString(secretKey.getEncoded());

String to SecretKey:

// decode the base64 encoded string
byte[] decodedKey = Base64.getDecoder().decode(encodedKey);
// rebuild key using SecretKeySpec
SecretKey originalKey = new SecretKeySpec(decodedKey, 0, decodedKey.length, "AES");

For Java 7 and before (including Android):

NOTE I: you can skip the Base64 encoding/decoding part and just store the byte[] in SQLite. That said, performing Base64 encoding/decoding is not an expensive operation and you can store strings in almost any DB without issues.

NOTE II: Earlier Java versions do not include a Base64 in one of the java.lang or java.util packages. It is however possible to use codecs from Apache Commons Codec, Bouncy Castle or Guava.

SecretKey to String:

// CREATE NEW KEY
// GET ENCODED VERSION OF KEY (THIS CAN BE STORED IN A DB)

SecretKey secretKey;
String stringKey;

try {secretKey = KeyGenerator.getInstance("AES").generateKey();}
catch (NoSuchAlgorithmException e) {/* LOG YOUR EXCEPTION */}

if (secretKey != null) {stringKey = Base64.encodeToString(secretKey.getEncoded(), Base64.DEFAULT)}

String to SecretKey:

// DECODE YOUR BASE64 STRING
// REBUILD KEY USING SecretKeySpec

byte[] encodedKey = Base64.decode(stringKey, Base64.DEFAULT);
SecretKey originalKey = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");

String to Secret key conversion/Vice Versa

Just follow below steps.

From key to string

`SecretKey secretKey = KeyGenerator.getInstance("ALGO_SECRET_KEY_GENERATOR").generateKey();
// Crate base64 string
String encodedKey = Base64.getEncoder().encodeToString(secretKey.getEncoded());`

From string to key

`// decode base64 string
byte[] decodedKey = Base64.getDecoder().decode(encodedKey);
// rebuild key using SecretKeySpec
SecretKey originalKey = new SecretKeySpec(decodedKey, 0, decodedKey.length, "ALGO_SECRET_KEY_GENERATOR"); `

It is available from api version 8

`SecretKey secretKey = null;
try {
secretKey = KeyGenerator.getInstance("AES").generateKey();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}

byte encoded[] = secretKey.getEncoded();
String str = android.util.Base64.encodeToString(encoded , 0);

byte decoded[] = android.util.Base64.decode(str , 0);

SecretKey originalKey = new SecretKeySpec(decoded, 0, decoded.length, "AES");'

Converting string to SecretKey

I would recommend to read Java 256-bit AES Password-Based Encryption. But here a quick overview. You will have to create a SecretKeyFactory, a KeySpec and then you can generate your SecretKey based on the KeySpec. From there, you can specify that your key is an AES through SecretKeySpec. There are some magic numbers here that you will have to consider. One is the password iterations, and the other the key sizes. For the example that I created below, I am using a 128 key instead of a 256. Sorry, I am not an expert in security topics so I used some examples that I have.

public static void main(String[] args) {
try {
//message to be encrypted
final String message = "This is a test message";
final String password = "password";

// Here the magic numbers
final int pswdIterations = 65536;
final int keySize = 128;

final byte[] saltBytes = {0, 1, 2, 3, 4, 5, 6};

SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), saltBytes, pswdIterations, keySize);
SecretKey secretKey = factory.generateSecret(spec);
SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");

// Instantiate the cipher
Cipher cipher = Cipher.getInstance("AES");

// Encrypt
cipher.init(Cipher.ENCRYPT_MODE, secret);
byte[] encrypted = cipher.doFinal(message.getBytes());
System.out.println("Original string: " + message);
System.out.println("Encrypted string: " + Arrays.toString(encrypted));

// Decrypt
cipher.init(Cipher.DECRYPT_MODE, secret);
byte[] decrypt_original = cipher.doFinal(encrypted);
String decrypt_originalString = new String(decrypt_original);
System.out.println("Decrypt string: " + decrypt_originalString);
} catch (NoSuchAlgorithmException | InvalidKeySpecException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException ex) {
Logger.getLogger(Sandbox.class.getName()).log(Level.SEVERE, null, ex);
}
}

Hopefully, this will help you.

Converting Key to String and back to Key Java

You never use your BASE64Decoder to un-base-64 your string.

Replace this:

        Key key = new SecretKeySpec(keyString.getBytes(),0,keyString.getBytes().length, "DES");     

with

        byte[] encodedKey = decoder.decodeBuffer(keyString);
Key key = new SecretKeySpec(encodedKey,0,encodedKey.length, "DES");

How to convert RSA Public key to string and vice versa?

Your main question seems to be "a java code to convert public key to string and vice versa" and this can be done with a few lines of code.

The full example code generates a RSA key pair, get the encoded form of the public key (as byte array) and encodes this in
Base64 encoding to a string. The encoding is done with the Android util class. Then the string needs to be transported to the
server, decoded to a byte array and this byte array runs into a key factory that "regenerates" the public key - voila.

Kindly note that the code has no exception handling and is for educational purpose only.

output:

Convert RSA public key into a string an dvice versa
publicKey: Sun RSA public key, 2048 bits
params: null
modulus: 18853651626448533042344052742185586831509096183921137436644620443732807152716528158465416708071104899767862289783079092216042499687784322092232163872332358586822678596223733228124113017356896219191227134298362353552882770945818159114272146532048929436504145362418430766823867890113522564795700689158702507402243560009550536419065620409534494384621580364502393563063483223294632627903706549112325066113361455750410642281763368591922729105346933211850575970566025026523917327761707615319008741255611490792106558703015066844972642677443110535667601315009551275389632601989979561472926080344790824117481932026867279062677
public exponent: 65537
publicKeyString: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlVmFPS+dIDcJILVZMM9hdQwEiLcHx7SVYF5gOrakPH7ZzilcOjWYcR47qktQAUu97JbLu3h3WPmm1nkgSXU1lVBoqc8pA1BHmzdvMK61A/F77nspDce0QqH5f5kQvYcuQrl+cCUvaTI/3/WBWwRIO2xGKMKRIgiBWDN/HVsqYU2O2pAJnLKQbz9NkkfGNVdzn4H21hi0shCVWCpt80zZkn0gm3oWtCGHOnyszXUOiw7inAdGkNGiZRyiFOUmFNRKLIYM3WiyU1NRGVrjto9NH/E53JdgSyBEu7kkWMLJqNuwj+DNQFu3Qq5VrNxwWggrwhFG+K0y0+Ed+scT003mlQIDAQAB
publicKeyServer: Sun RSA public key, 2048 bits
params: null
modulus: 18853651626448533042344052742185586831509096183921137436644620443732807152716528158465416708071104899767862289783079092216042499687784322092232163872332358586822678596223733228124113017356896219191227134298362353552882770945818159114272146532048929436504145362418430766823867890113522564795700689158702507402243560009550536419065620409534494384621580364502393563063483223294632627903706549112325066113361455750410642281763368591922729105346933211850575970566025026523917327761707615319008741255611490792106558703015066844972642677443110535667601315009551275389632601989979561472926080344790824117481932026867279062677
public exponent: 65537

code:

import android.util.Base64;

import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;

public class Main {
public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException {
System.out.println("Convert RSA public key into a string an dvice versa");
// generate a RSA key pair
KeyPairGenerator keygen = KeyPairGenerator.getInstance("RSA");
keygen.initialize(2048, new SecureRandom());
KeyPair keyPair = keygen.generateKeyPair();
PrivateKey privateKey = keyPair.getPrivate();
PublicKey publicKey = keyPair.getPublic();
System.out.println("publicKey: " + publicKey);
// get encoded form (byte array)
byte[] publicKeyByte = publicKey.getEncoded();
// Base64 encoded string
String publicKeyString = Base64.encodeToString(publicKeyByte, Base64.NO_WRAP);
System.out.println("publicKeyString: " + publicKeyString);
// ... transport to server
// Base64 decoding to byte array
byte[] publicKeyByteServer = Base64.decode(publicKeyString, Base64.NO_WRAP);
// generate the publicKey
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKeyServer = (PublicKey) keyFactory.generatePublic(new X509EncodedKeySpec(publicKeyByteServer));
System.out.println("publicKeyServer: " + publicKeyServer);
}
}

Converting Strings to encryption keys and vice versa java

Public keys are stored using a X509EncodedKeySpec as you have, but Private keys use the PKCS8EncodedKeySpec. For example like this:

public static PrivateKey loadPrivateKey(String key64) throws GeneralSecurityException {
byte[] clear = base64Decode(key64);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(clear);
KeyFactory fact = KeyFactory.getInstance("DSA");
PrivateKey priv = fact.generatePrivate(keySpec);
Arrays.fill(clear, (byte) 0);
return priv;
}

public static PublicKey loadPublicKey(String stored) throws GeneralSecurityException {
byte[] data = base64Decode(stored);
X509EncodedKeySpec spec = new X509EncodedKeySpec(data);
KeyFactory fact = KeyFactory.getInstance("DSA");
return fact.generatePublic(spec);
}

public static String savePrivateKey(PrivateKey priv) throws GeneralSecurityException {
KeyFactory fact = KeyFactory.getInstance("DSA");
PKCS8EncodedKeySpec spec = fact.getKeySpec(priv,
PKCS8EncodedKeySpec.class);
byte[] packed = spec.getEncoded();
String key64 = base64Encode(packed);

Arrays.fill(packed, (byte) 0);
return key64;
}

public static String savePublicKey(PublicKey publ) throws GeneralSecurityException {
KeyFactory fact = KeyFactory.getInstance("DSA");
X509EncodedKeySpec spec = fact.getKeySpec(publ,
X509EncodedKeySpec.class);
return base64Encode(spec.getEncoded());
}

public static void main(String[] args) throws Exception {
KeyPairGenerator gen = KeyPairGenerator.getInstance("DSA");
KeyPair pair = gen.generateKeyPair();

String pubKey = savePublicKey(pair.getPublic());
PublicKey pubSaved = loadPublicKey(pubKey);
System.out.println(pair.getPublic()+"\n"+pubSaved);

String privKey = savePrivateKey(pair.getPrivate());
PrivateKey privSaved = loadPrivateKey(privKey);
System.out.println(pair.getPrivate()+"\n"+privSaved);
}


Related Topics



Leave a reply



Submit