· 6 years ago · Aug 19, 2019, 11:10 PM
1public static List<SecretKeyRequestModel> createSessionKeys(PrivateKey pk, List<Certificate> certificates) throws KomandorException {
2 List<SecretKeyRequestModel> keys = new ArrayList<>();
3 try {
4 /* Генерирование симметричного ключа с параметрами шифрования из контрольной панели*/
5 final KeyGenerator keyGen = KeyGenerator.getInstance(CIPHER_ALG, JCSP.PROVIDER_NAME);
6 final SecretKey simm = keyGen.generateKey();
7
8 final byte[] iv = new byte[RND_LENGTH];
9 final SecureRandom random = SecureRandom.getInstance(RANDOM_ALG, JCSP.PROVIDER_NAME);
10 random.nextBytes(iv);
11 final byte[] ivLength = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(iv.length).array();
12
13 Cipher cipher = Cipher.getInstance(CIPHER_ALG + CIPHER_KEY_ALG_PARAMS, JCSP.PROVIDER_NAME);
14
15 for (Certificate certificate : certificates) {
16 X509Certificate cert = decodeBase64Certificate(certificate.getBase64());
17
18 /* Генерирование начальной синхропосылки для выработки ключа согласования*/
19 final byte[] sv = new byte[RND_LENGTH];
20 random.nextBytes(sv);
21
22 /* Выработка ключа согласования c SV*/
23 SecretKey senderAgree = generateKeyAgreement(pk, cert, sv);
24
25 /*Зашифрование симметричного ключа на ключе согласования*/
26
27 cipher.init(Cipher.WRAP_MODE, senderAgree, new IvParameterSpec(sv));
28 final byte[] wrappedKey = cipher.wrap(simm);
29
30 byte[] simpleKeyBLOBHeader = {
31 0x01,
32 0x20,
33 0x00, 0x00,
34 0x1e, 0x66, 0x00, 0x00,
35 (byte) 0xfd, 0x51, 0x4a, 0x37,
36 0x1e, 0x66, 0x00, 0x00,
37 };
38
39 final Asn1BerDecodeBuffer buf = new Asn1BerDecodeBuffer(wrappedKey);
40 final Gost28147_89_EncryptedKey ek = new Gost28147_89_EncryptedKey();
41
42 ek.decode(buf);
43 byte[] encryptedKey = ek.encryptedKey.value;
44 byte[] macKey = ek.macKey.value;
45
46 byte[] encryptedParams = {
47 0x30, 0x0B, 0x06, 0x09, 0x2A, (byte) 0x85, 0x03, 0x07, 0x01, 0x02, 0x05, 0x01, 0x01
48 };
49
50 int blobLength = simpleKeyBLOBHeader.length + sv.length + encryptedKey.length + macKey.length + encryptedParams.length;
51 final byte[] bBlobLength = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(blobLength).array();
52
53
54 ByteArrayOutputStream baos = new ByteArrayOutputStream();
55 baos.write(bBlobLength);
56 baos.write(simpleKeyBLOBHeader);
57 baos.write(sv);
58 baos.write(encryptedKey);
59 baos.write(macKey);
60 baos.write(encryptedParams);
61 baos.write(ivLength);
62 baos.write(iv);
63
64 byte[] sessionKey = baos.toByteArray();
65
66 SecretKeyRequestModel key = new SecretKeyRequestModel(certificate.getPid(), certificate.getCid(), sessionKey);
67 keys.add(key);
68 }
69 } catch (Exception e) {
70 throw new KomandorException(e);
71 }
72
73 return keys;
74 }
75
76private static SecretKey generateKeyAgreement(PrivateKey pk, X509Certificate partnerCert, byte[] sv) throws NoSuchProviderException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException {
77 final IvParameterSpec ivspec = new IvParameterSpec(sv);
78 final KeyAgreement keyAgree = KeyAgreement.getInstance(pk.getAlgorithm(), JCSP.PROVIDER_NAME);
79 keyAgree.init(pk, ivspec, null);
80 keyAgree.doPhase(partnerCert.getPublicKey(), true);
81 return keyAgree.generateSecret(CIPHER_ALG);
82 }