1 package civitas.crypto;
2
3 import java.math.BigInteger;
4 import java.security.Key;
5 import java.security.KeyFactory;
6 import java.security.KeyPairGenerator;
7 import java.security.Security;
8 import java.security.Signature;
9 import java.util.Random;
10
11 import javax.crypto.Cipher;
12 import javax.crypto.KeyGenerator;
13 import javax.crypto.SecretKeyFactory;
14
15 import org.bouncycastle.jce.provider.BouncyCastleProvider;
16 import org.springframework.beans.factory.annotation.Autowired;
17 import org.springframework.stereotype.Service;
18
19 import civitas.util.CivitasBigInteger;
20 import civitas.util.CivitasBigIntegerFactory;
21
22 @Service
23 public class CryptoBase implements Constants {
24 public SecretKeyFactory sharedKeyFactory;
25 public KeyFactory publicKeyFactory;
26 public Signature rsaSigner;
27
28 @Autowired
29 GetPublicKeyGeneratorService getPublicKeyGenerator;
30
31 @Autowired
32 GetSharedKeyGeneratorService getSharedKeyGenerator;
33
34 public CryptoBase() {
35 var bc = new BouncyCastleProvider();
36 Security.addProvider(bc);
37 try {
38 sharedKeyFactory = SecretKeyFactory.getInstance(SHARED_KEY_ALG, SHARED_KEY_PROVIDER);
39 publicKeyFactory = KeyFactory.getInstance(PUBLIC_KEY_ALG, PUBLIC_KEY_PROVIDER);
40 rsaSigner = Signature.getInstance(PUBLIC_KEY_SIGNATURE_ALG, PUBLIC_KEY_PROVIDER);
41 } catch (Exception e) {
42 throw new CryptoError(e);
43 }
44 }
45
46 public CivitasBigInteger obtainProbablePrime(final int bitLenght) {
47 return CivitasBigIntegerFactory.obtain(new BigInteger(bitLenght, CERTAINTY, RANDOM));
48 }
49
50 public CivitasBigInteger generateRandomElement(final CivitasBigInteger n) {
51 CivitasBigInteger randomElement;
52 do {
53 randomElement = CivitasBigIntegerFactory.obtain(n.bitLength(), RANDOM);
54 } while (ZERO.equals(randomElement) || randomElement.compareTo(n) >= 0);
55 return randomElement;
56 }
57
58 public Random getRandomGenerator() {
59 return RANDOM;
60 }
61
62 public byte[] doCrypto(
63 final String alg, final String provider, final Key skey, final int mode, final byte[] input) {
64 Cipher cipher;
65 try {
66 cipher = Cipher.getInstance(alg, provider);
67 cipher.init(mode, skey);
68 return cipher.doFinal(input);
69 } catch (Exception e) {
70 throw new CryptoError("cannot do crypto", e);
71 }
72 }
73
74 public void nextBytes(final byte[] bs) {
75 RANDOM.nextBytes(bs);
76 }
77
78 public KeyPairGenerator getPublicKeyGenerator(final int keysize) {
79 return getPublicKeyGenerator.apply(keysize);
80 }
81
82 public KeyGenerator getSharedKeyGenerator(final int sharedKeySize) {
83 return getSharedKeyGenerator.apply(sharedKeySize);
84 }
85 }