Skip to content

Instantly share code, notes, and snippets.

@utkarshgpta
Created February 29, 2020 19:39
Show Gist options
  • Save utkarshgpta/db36ebc31b35de59f7b928b5c971a81d to your computer and use it in GitHub Desktop.
Save utkarshgpta/db36ebc31b35de59f7b928b5c971a81d to your computer and use it in GitHub Desktop.
IPFS and Encrption Utility Files
package ipfs;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.AbstractMap;
import java.util.Base64;
import java.util.Map;
public class EncryptionUtil {
public static PublicKey getPublicKey(String base64PublicKey){
PublicKey publicKey = null;
try{
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(base64PublicKey.getBytes()));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
publicKey = keyFactory.generatePublic(keySpec);
return publicKey;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
return publicKey;
}
public static PrivateKey getPrivateKey(String base64PrivateKey){
PrivateKey privateKey = null;
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(base64PrivateKey.getBytes()));
KeyFactory keyFactory = null;
try {
keyFactory = KeyFactory.getInstance("RSA");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
try {
privateKey = keyFactory.generatePrivate(keySpec);
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
return privateKey;
}
public static Map.Entry<byte[], byte[]> encryptFile(byte[] inputBytes, String publicKey) {
// Due to size constraints imposed by RSA algorithm, we encrypt a file using a AES Secret Key
// and generate a cipher which is sent along with RSA encrypted 'AES Secret Key' which the user
// can decrypt on its end using it's own private key.
SecretKey aesSecKey = null;
try {
aesSecKey = EncryptionUtil.generateAESSecretKey(128);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
byte[] encryptedAESCipher = new byte[0];
try {
encryptedAESCipher = EncryptionUtil.encryptAES(inputBytes, aesSecKey);
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
byte[] encryptedAESKey = new byte[0]; // Encrypted with public key of receiving party
try {
encryptedAESKey = EncryptionUtil.encryptRSA(aesSecKey.getEncoded(), publicKey);
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
return new AbstractMap.SimpleEntry<byte[], byte[]>(encryptedAESKey, encryptedAESCipher);
}
public static byte[] encryptRSA(byte[] data, String publicKey) throws NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, getPublicKey(publicKey));
return cipher.doFinal(data);
}
public static byte[] encryptAES(byte[] data, SecretKey secKey) throws NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException {
Cipher aesCipher = Cipher.getInstance("AES");
aesCipher.init(Cipher.ENCRYPT_MODE, secKey);
byte[] byteCipherText = aesCipher.doFinal(data);
return byteCipherText;
}
public static byte[] decryptRSA(byte[] data, PrivateKey privateKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(data);
}
public static byte[] decryptAES(byte[] data, SecretKey secKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
Cipher aesCipher = Cipher.getInstance("AES");
aesCipher.init(Cipher.DECRYPT_MODE, secKey);
return aesCipher.doFinal(data);
}
public static SecretKey generateAESSecretKey(int initializer) throws NoSuchAlgorithmException {
KeyGenerator generator = KeyGenerator.getInstance("AES");
generator.init(initializer);
SecretKey secKey = generator.generateKey();
return secKey;
}
public static KeyPair generateRSAKeyPair(int keySize) {
KeyPairGenerator keyPairGenerator = null;
KeyPair keyPair = null;
try {
keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(keySize);
SecureRandom secureRandom = new SecureRandom();
keyPair = keyPairGenerator.generateKeyPair();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return keyPair;
}
public static byte[] decryptFile(byte[] encryptedAESKey, PrivateKey privateKey, byte[] retrievedEncryptedAESCipher) {
byte[] decryptedAESKey = null; // Decrypt AES Secret Key
try {
decryptedAESKey = EncryptionUtil.decryptRSA(encryptedAESKey, privateKey);
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
SecretKey originalAESKey = new SecretKeySpec(decryptedAESKey, 0, decryptedAESKey.length, "AES");
byte[] decryptedAESCipher = null; // decrypted back to original byte[] before encryption
try {
decryptedAESCipher = EncryptionUtil.decryptAES(retrievedEncryptedAESCipher, originalAESKey);
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
return decryptedAESCipher;
}
public static byte[] getBytesFromFilePath(String filePath) {
Path fPath = Paths.get(filePath);
byte[] inputBytes = null;
try {
inputBytes = Files.readAllBytes(fPath);
} catch (IOException e) {
e.printStackTrace();
}
return inputBytes;
}
}
package ipfs;
import io.ipfs.api.IPFS;
import io.ipfs.api.MerkleNode;
import io.ipfs.api.NamedStreamable;
import io.ipfs.multihash.Multihash;
import ipfs.config.IPFSConfig;
import java.io.*;
import java.util.Map;
public class IPFSUtil {
private static IPFSUtil instance;
private IPFS ipfs;
private IPFSUtil() {
Map<String, String> ipfsConfig = null;
try {
ipfsConfig = IPFSConfig.loadConfiguration();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
String ipfsNodeAddress;
String ipfsHostNameEnv = System.getenv("IPFS_HOSTNAME");
if(ipfsHostNameEnv == null || ipfsHostNameEnv =="")
ipfsNodeAddress = ipfsConfig.getOrDefault("ipfsNodeAddress", "/ip4/127.0.0.1/tcp/5001");
else ipfsNodeAddress = "/ip4/" + ipfsHostNameEnv + "/tcp/5001";
ipfs = new IPFS(ipfsNodeAddress);
}
private static class SingletonHelper{
private static final IPFSUtil INSTANCE = new IPFSUtil();
}
public static IPFSUtil getInstance(){
return SingletonHelper.INSTANCE;
}
public static void saveFileToLocation(byte[] byteArray, String outputFilePath) throws IOException {
OutputStream out = new FileOutputStream(outputFilePath);
out.write(byteArray);
out.close();
}
public String addFileToIPFSNetworkByFilePath(String filePath) {
long startTime = System.nanoTime();
try {
NamedStreamable.InputStreamWrapper is = new NamedStreamable.InputStreamWrapper(new FileInputStream(filePath));
MerkleNode response = ipfs.add(is).get(0);
// System.out.println(response.toJSONString());
// System.out.println("Hash (base 58): " + response.name.get() + " - " + response.hash.toBase58());
long endTime = System.nanoTime();
long duration = (endTime - startTime);
System.out.println("Added file with hash " + response.hash.toBase58() + " to IPFS in " + duration/1000000 + " milliseconds.");
return response.hash.toBase58();
} catch (IOException ex) {
throw new RuntimeException("Error while communicating with the IPFS node", ex);
}
}
public String addFileToIPFSNetworkUsingBytes(byte[] inputFileBytes) {
long startTime = System.nanoTime();
NamedStreamable.ByteArrayWrapper file = new NamedStreamable.ByteArrayWrapper(inputFileBytes);
try {
MerkleNode addResult = ipfs.add(file).get(0);
long endTime = System.nanoTime();
long duration = (endTime - startTime);
System.out.println("Added file with hash " + addResult.hash.toBase58() + " to IPFS in " + duration / 1000000 + " milliseconds.");
return addResult.hash.toBase58();
}
catch (IOException ex) {
throw new RuntimeException("Error while communicating with the IPFS node", ex);
}
}
public byte[] getFileFromIPFSNetwork(String ipfsHash) {
try {
long startTime = System.nanoTime();
Multihash multihash = Multihash.fromBase58(ipfsHash);
byte[] fileByteArray = ipfs.cat(multihash);
long endTime = System.nanoTime();
long duration = (endTime - startTime);
System.out.println("Retrieved file hash " + ipfsHash + " from IPFS in " + duration/1000000 + " milliseconds.");
return fileByteArray;
} catch (IOException ex) {
throw new RuntimeException("Error whilst communicating with the IPFS node", ex);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment