mirror of
https://github.com/sismics/docs.git
synced 2024-11-26 07:34: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)
|
@Column(name = "USE_PASSWORD_C", nullable = false, length = 100)
|
||||||
private String password;
|
private String password;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User's private key.
|
||||||
|
*/
|
||||||
|
@Column(name = "USE_PRIVATEKEY_C", nullable = false, length = 100)
|
||||||
|
private String privateKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Email address.
|
* Email address.
|
||||||
*/
|
*/
|
||||||
@ -257,6 +263,22 @@ public class User {
|
|||||||
this.deleteDate = deleteDate;
|
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
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return Objects.toStringHelper(this)
|
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.awt.image.BufferedImage;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.List;
|
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 javax.imageio.ImageIO;
|
||||||
|
|
||||||
import net.sourceforge.tess4j.Tesseract;
|
import net.sourceforge.tess4j.Tesseract;
|
||||||
@ -28,7 +21,6 @@ import org.imgscalr.Scalr.Mode;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
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.Document;
|
||||||
import com.sismics.docs.core.model.jpa.File;
|
import com.sismics.docs.core.model.jpa.File;
|
||||||
import com.sismics.util.ImageUtil;
|
import com.sismics.util.ImageUtil;
|
||||||
@ -207,41 +199,4 @@ public class FileUtil {
|
|||||||
thumbnailFile.delete();
|
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.dao.jpa.dto.UserDto;
|
||||||
import com.sismics.docs.core.model.jpa.AuthenticationToken;
|
import com.sismics.docs.core.model.jpa.AuthenticationToken;
|
||||||
import com.sismics.docs.core.model.jpa.User;
|
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.PaginatedList;
|
||||||
import com.sismics.docs.core.util.jpa.PaginatedLists;
|
import com.sismics.docs.core.util.jpa.PaginatedLists;
|
||||||
import com.sismics.docs.core.util.jpa.SortCriteria;
|
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.MediaType;
|
||||||
import javax.ws.rs.core.NewCookie;
|
import javax.ws.rs.core.NewCookie;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
|
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -76,6 +79,11 @@ public class UserResource extends BaseResource {
|
|||||||
user.setUsername(username);
|
user.setUsername(username);
|
||||||
user.setPassword(password);
|
user.setPassword(password);
|
||||||
user.setEmail(email);
|
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());
|
user.setCreateDate(new Date());
|
||||||
|
|
||||||
if (localeId == null) {
|
if (localeId == null) {
|
||||||
|
Loading…
Reference in New Issue
Block a user