mirror of
https://github.com/sismics/docs.git
synced 2024-11-22 14:07:55 +01:00
File encryption utilities
This commit is contained in:
parent
0bc658a396
commit
00b00f0d0c
@ -47,6 +47,12 @@ public class User {
|
||||
@Column(name = "USE_PASSWORD_C", nullable = false, length = 100)
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* User's private key.
|
||||
*/
|
||||
@Column(name = "USE_PRIVATEKEY_C", nullable = false, length = 100)
|
||||
private String privateKey;
|
||||
|
||||
/**
|
||||
* Email address.
|
||||
*/
|
||||
@ -257,6 +263,22 @@ public class User {
|
||||
this.deleteDate = deleteDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter de privateKey.
|
||||
* @return privateKey
|
||||
*/
|
||||
public String getPrivateKey() {
|
||||
return privateKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter de privateKey.
|
||||
* @param privateKey privateKey
|
||||
*/
|
||||
public void setPrivateKey(String privateKey) {
|
||||
this.privateKey = privateKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Objects.toStringHelper(this)
|
||||
|
@ -0,0 +1,91 @@
|
||||
package com.sismics.docs.core.util;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.Security;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.CipherInputStream;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
|
||||
/**
|
||||
* Encryption utilities.
|
||||
*
|
||||
* @author bgamard
|
||||
*/
|
||||
public class EncryptionUtil {
|
||||
|
||||
/**
|
||||
* Salt.
|
||||
*/
|
||||
private static final String SALT = "LEpxZmm2SMu2PeKzPNrar2rhVAS6LrrgvXKeL9uyXC4vgKHg";
|
||||
|
||||
/**
|
||||
* Generate a private key.
|
||||
*
|
||||
* @return New random private key
|
||||
* @throws NoSuchAlgorithmException
|
||||
*/
|
||||
public static String generatePrivateKey() throws NoSuchAlgorithmException {
|
||||
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
|
||||
return new BigInteger(176, random).toString(32);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt an InputStream using the specified private key.
|
||||
*
|
||||
* @param is InputStream to encrypt
|
||||
* @param privateKey Private key
|
||||
* @return Encrypted stream
|
||||
* @throws Exception
|
||||
*/
|
||||
public static InputStream encryptStream(InputStream is, String privateKey) throws Exception {
|
||||
checkBouncyCastleProvider();
|
||||
return new CipherInputStream(is, getCipher(privateKey, Cipher.ENCRYPT_MODE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypt an InputStream using the specified private key.
|
||||
*
|
||||
* @param is InputStream to encrypt
|
||||
* @param privateKey Private key
|
||||
* @return Encrypted stream
|
||||
* @throws Exception
|
||||
*/
|
||||
public static InputStream decryptStream(InputStream is, String privateKey) throws Exception {
|
||||
checkBouncyCastleProvider();
|
||||
return new CipherInputStream(is, getCipher(privateKey, Cipher.DECRYPT_MODE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a Cipher.
|
||||
*
|
||||
* @param privateKey Private key
|
||||
* @param mode Mode (encrypt or decrypt)
|
||||
* @return Cipher
|
||||
* @throws Exception
|
||||
*/
|
||||
private static Cipher getCipher(String privateKey, int mode) throws Exception {
|
||||
PBEKeySpec keySpec = new PBEKeySpec(privateKey.toCharArray(), SALT.getBytes(), 2000, 256);
|
||||
SecretKeyFactory skf = SecretKeyFactory.getInstance("PBEWITHSHA256AND256BITAES-CBC-BC");
|
||||
SecretKey desKey = skf.generateSecret(keySpec);
|
||||
Cipher cipher = Cipher.getInstance("AES/CTR/NOPADDING");
|
||||
cipher.init(mode, desKey);
|
||||
return cipher;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the Bouncy Castle provider if necessary.
|
||||
*/
|
||||
private static void checkBouncyCastleProvider() {
|
||||
if (Security.getProvider("BouncyCastleProvider") == null) {
|
||||
Security.insertProviderAt(new BouncyCastleProvider(), 1);
|
||||
}
|
||||
}
|
||||
}
|
@ -3,18 +3,11 @@ package com.sismics.docs.core.util;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.CipherInputStream;
|
||||
import javax.crypto.CipherOutputStream;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import net.sourceforge.tess4j.Tesseract;
|
||||
@ -28,7 +21,6 @@ import org.imgscalr.Scalr.Mode;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.common.io.ByteStreams;
|
||||
import com.sismics.docs.core.model.jpa.Document;
|
||||
import com.sismics.docs.core.model.jpa.File;
|
||||
import com.sismics.util.ImageUtil;
|
||||
@ -207,41 +199,4 @@ public class FileUtil {
|
||||
thumbnailFile.delete();
|
||||
}
|
||||
}
|
||||
|
||||
// Security.insertProviderAt(new BouncyCastleProvider(), 1);
|
||||
// String key = "pwd";
|
||||
//
|
||||
// FileInputStream fis = new FileInputStream("plain.jpg");
|
||||
// FileOutputStream fos = new FileOutputStream("encrypted.jpg");
|
||||
// encrypt(key, fis, fos);
|
||||
//
|
||||
// FileInputStream fis2 = new FileInputStream("encrypted.jpg");
|
||||
// FileOutputStream fos2 = new FileOutputStream("decrypted.jpg");
|
||||
// decrypt(key, fis2, fos2);
|
||||
|
||||
public static void encrypt(String key, InputStream is, OutputStream os) throws Throwable {
|
||||
encryptOrDecrypt(key, Cipher.ENCRYPT_MODE, is, os);
|
||||
}
|
||||
|
||||
public static void decrypt(String key, InputStream is, OutputStream os) throws Throwable {
|
||||
encryptOrDecrypt(key, Cipher.DECRYPT_MODE, is, os);
|
||||
}
|
||||
|
||||
public static void encryptOrDecrypt(String key, int mode, InputStream is, OutputStream os) throws Throwable {
|
||||
|
||||
PBEKeySpec keySpec = new PBEKeySpec(key.toCharArray(), "salt".getBytes(), 2000, 256);
|
||||
SecretKeyFactory skf = SecretKeyFactory.getInstance("PBEWITHSHA256AND256BITAES-CBC-BC");
|
||||
SecretKey desKey = skf.generateSecret(keySpec);
|
||||
Cipher cipher = Cipher.getInstance("AES/CTR/NOPADDING");
|
||||
|
||||
if (mode == Cipher.ENCRYPT_MODE) {
|
||||
cipher.init(Cipher.ENCRYPT_MODE, desKey);
|
||||
CipherInputStream cis = new CipherInputStream(is, cipher);
|
||||
ByteStreams.copy(cis, os);
|
||||
} else if (mode == Cipher.DECRYPT_MODE) {
|
||||
cipher.init(Cipher.DECRYPT_MODE, desKey);
|
||||
CipherOutputStream cos = new CipherOutputStream(os, cipher);
|
||||
ByteStreams.copy(is, cos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,51 @@
|
||||
package com.sismics.docs.core.util;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.bouncycastle.util.io.Streams;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.io.ByteStreams;
|
||||
|
||||
/**
|
||||
* Test of the encryption utilities.
|
||||
*
|
||||
* @author bgamard
|
||||
*/
|
||||
public class TestEncryptUtil {
|
||||
|
||||
/**
|
||||
* Test private key.
|
||||
*/
|
||||
String pk = "OnceUponATime";
|
||||
|
||||
@Test
|
||||
public void generatePrivateKeyTest() throws Exception {
|
||||
String key = EncryptionUtil.generatePrivateKey();
|
||||
System.out.println(key);
|
||||
Assert.assertFalse(Strings.isNullOrEmpty(key));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void encryptStreamTest() throws Exception {
|
||||
InputStream inputStream = EncryptionUtil.encryptStream(this.getClass().getResourceAsStream("/file/udhr.pdf"), pk);
|
||||
byte[] encryptedData = Streams.readAll(inputStream);
|
||||
byte[] assertData = Streams.readAll(this.getClass().getResourceAsStream("/file/udhr_encrypted.pdf"));
|
||||
Assert.assertTrue(ByteStreams.equal(
|
||||
ByteStreams.newInputStreamSupplier(encryptedData),
|
||||
ByteStreams.newInputStreamSupplier(assertData)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void decryptStreamTest() throws Exception {
|
||||
InputStream inputStream = EncryptionUtil.decryptStream(this.getClass().getResourceAsStream("/file/udhr_encrypted.pdf"), pk);
|
||||
byte[] encryptedData = Streams.readAll(inputStream);
|
||||
byte[] assertData = Streams.readAll(this.getClass().getResourceAsStream("/file/udhr.pdf"));
|
||||
Assert.assertTrue(ByteStreams.equal(
|
||||
ByteStreams.newInputStreamSupplier(encryptedData),
|
||||
ByteStreams.newInputStreamSupplier(assertData)));
|
||||
}
|
||||
}
|
BIN
docs-core/src/test/resources/file/udhr.pdf
Normal file
BIN
docs-core/src/test/resources/file/udhr.pdf
Normal file
Binary file not shown.
BIN
docs-core/src/test/resources/file/udhr_encrypted.pdf
Normal file
BIN
docs-core/src/test/resources/file/udhr_encrypted.pdf
Normal file
Binary file not shown.
@ -7,6 +7,7 @@ import com.sismics.docs.core.dao.jpa.UserDao;
|
||||
import com.sismics.docs.core.dao.jpa.dto.UserDto;
|
||||
import com.sismics.docs.core.model.jpa.AuthenticationToken;
|
||||
import com.sismics.docs.core.model.jpa.User;
|
||||
import com.sismics.docs.core.util.EncryptionUtil;
|
||||
import com.sismics.docs.core.util.jpa.PaginatedList;
|
||||
import com.sismics.docs.core.util.jpa.PaginatedLists;
|
||||
import com.sismics.docs.core.util.jpa.SortCriteria;
|
||||
@ -28,6 +29,8 @@ import javax.ws.rs.*;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.NewCookie;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
@ -76,6 +79,11 @@ public class UserResource extends BaseResource {
|
||||
user.setUsername(username);
|
||||
user.setPassword(password);
|
||||
user.setEmail(email);
|
||||
try {
|
||||
user.setPrivateKey(EncryptionUtil.generatePrivateKey());
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new ServerException("PrivateKeyError", "Error while generating a private key", e);
|
||||
}
|
||||
user.setCreateDate(new Date());
|
||||
|
||||
if (localeId == null) {
|
||||
|
Loading…
Reference in New Issue
Block a user