· 6 years ago · Aug 19, 2019, 11:12 PM
1public static DecryptedSessionKey decryptSessionKey(PrivateKey pk, EncryptedSessionKey encryptedSessionKey) throws KomandorException {
2 SecretKey key_ = null;
3 byte[] iv = null;
4 try {
5 int sizeLength = 4;
6 byte[] bKey = Base64.decode(encryptedSessionKey.getEncryptedKey(), Base64.NO_WRAP);
7
8 byte[] bBlobLength = SystemUtils.reverseByteArray(Arrays.copyOfRange(bKey, 0, sizeLength));
9 int blobLength = ByteBuffer.wrap(bBlobLength).getInt();
10
11 byte[] bSimpleBlob = Arrays.copyOfRange(bKey, sizeLength, sizeLength + blobLength);
12 byte[] bBlobHeader = Arrays.copyOfRange(bSimpleBlob, 0, 16);
13 byte[] sv = Arrays.copyOfRange(bSimpleBlob, 16, 24);
14 byte[] bEncryptedKey = Arrays.copyOfRange(bSimpleBlob, 24, 24 + 32);
15 byte[] bMacKey = Arrays.copyOfRange(bSimpleBlob, 56, 56 + 4);
16 byte[] bEncryptedParams = Arrays.copyOfRange(bSimpleBlob, 60, blobLength);
17
18 // Получаем IV вектор
19 int IVStart = sizeLength + blobLength;
20 byte[] bIVLength = SystemUtils.reverseByteArray(Arrays.copyOfRange(bKey, IVStart, IVStart + sizeLength));
21 int IVLength = ByteBuffer.wrap(bIVLength).getInt();
22 iv = Arrays.copyOfRange(bKey, IVStart + sizeLength, IVStart + sizeLength + IVLength);
23
24 // Получаем зашифрованный ключ
25 final Gost28147_89_EncryptedKey ek = new Gost28147_89_EncryptedKey();
26 ek.encryptedKey = new Gost28147_89_Key(bEncryptedKey);
27 ek.macKey = new Gost28147_89_MAC(bMacKey);
28 final Asn1BerEncodeBuffer ebuf = new Asn1BerEncodeBuffer();
29 ek.encode(ebuf);
30 final byte[] wrap = ebuf.getMsgCopy();
31
32 // Генерируем ключ согласования
33 SecretKey responderAgree = generateKeyAgreement(pk, encryptedSessionKey.getCertificate(), sv);
34
35 if (responderAgree == null) {
36 throw new KomandorException("Key agreement is null");
37 }
38
39 // Расшифровываем ключ
40 Cipher cipher = Cipher.getInstance(CIPHER_ALG + CIPHER_KEY_ALG_PARAMS);
41 cipher.init(Cipher.UNWRAP_MODE, responderAgree);
42 key_ = (SecretKey) cipher.unwrap(wrap, null, Cipher.SECRET_KEY);
43 } catch (Exception e) {
44 throw new KomandorException(e);
45 }
46 return new DecryptedSessionKey(key_, iv);
47 }
48
49private static SecretKey generateKeyAgreement(PrivateKey pk, X509Certificate partnerCert, byte[] sv) throws NoSuchProviderException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException {
50 final IvParameterSpec ivspec = new IvParameterSpec(sv);
51 final KeyAgreement keyAgree = KeyAgreement.getInstance(pk.getAlgorithm(), JCSP.PROVIDER_NAME);
52 keyAgree.init(pk, ivspec, null);
53 keyAgree.doPhase(partnerCert.getPublicKey(), true);
54 return keyAgree.generateSecret(CIPHER_ALG);
55 }