Created
August 7, 2019 19:09
-
-
Save ReFLeXive007/7cf10c9edbca3550f3b3c4ad6ebc594a to your computer and use it in GitHub Desktop.
Сессионные ключи
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static List<SecretKeyRequestModel> createSessionKeys(PrivateKey pk, List<Certificate> certificates) throws KomandorException { | |
List<SecretKeyRequestModel> keys = new ArrayList<>(); | |
try { | |
/* Генерирование симметричного ключа с параметрами шифрования из контрольной панели*/ | |
final KeyGenerator keyGen = KeyGenerator.getInstance(CIPHER_ALG, JCSP.PROVIDER_NAME); | |
final SecretKey simm = keyGen.generateKey(); | |
final byte[] iv = new byte[RND_LENGTH]; | |
final SecureRandom random = SecureRandom.getInstance(RANDOM_ALG, JCSP.PROVIDER_NAME); | |
random.nextBytes(iv); | |
final byte[] ivLength = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(iv.length).array(); | |
Cipher cipher = Cipher.getInstance(CIPHER_ALG + CIPHER_KEY_ALG_PARAMS, JCSP.PROVIDER_NAME); | |
for (Certificate certificate : certificates) { | |
X509Certificate cert = decodeBase64Certificate(certificate.getBase64()); | |
/* Генерирование начальной синхропосылки для выработки ключа согласования*/ | |
final byte[] sv = new byte[RND_LENGTH]; | |
random.nextBytes(sv); | |
/* Выработка ключа согласования c SV*/ | |
SecretKey senderAgree = generateKeyAgreement(pk, cert, sv); | |
/*Зашифрование симметричного ключа на ключе согласования*/ | |
cipher.init(Cipher.WRAP_MODE, senderAgree, new IvParameterSpec(sv)); | |
final byte[] wrappedKey = cipher.wrap(simm); | |
byte[] simpleKeyBLOBHeader = { | |
0x01, | |
0x20, | |
0x00, 0x00, | |
0x1e, 0x66, 0x00, 0x00, | |
(byte) 0xfd, 0x51, 0x4a, 0x37, | |
0x1e, 0x66, 0x00, 0x00, | |
}; | |
final Asn1BerDecodeBuffer buf = new Asn1BerDecodeBuffer(wrappedKey); | |
final Gost28147_89_EncryptedKey ek = new Gost28147_89_EncryptedKey(); | |
ek.decode(buf); | |
byte[] encryptedKey = ek.encryptedKey.value; | |
byte[] macKey = ek.macKey.value; | |
byte[] encryptedParams = { | |
0x30, 0x0B, 0x06, 0x09, 0x2A, (byte) 0x85, 0x03, 0x07, 0x01, 0x02, 0x05, 0x01, 0x01 | |
}; | |
int blobLength = simpleKeyBLOBHeader.length + sv.length + encryptedKey.length + macKey.length + encryptedParams.length; | |
final byte[] bBlobLength = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(blobLength).array(); | |
ByteArrayOutputStream baos = new ByteArrayOutputStream(); | |
baos.write(bBlobLength); | |
baos.write(simpleKeyBLOBHeader); | |
baos.write(sv); | |
baos.write(encryptedKey); | |
baos.write(macKey); | |
baos.write(encryptedParams); | |
baos.write(ivLength); | |
baos.write(iv); | |
byte[] sessionKey = baos.toByteArray(); | |
SecretKeyRequestModel key = new SecretKeyRequestModel(certificate.getPid(), certificate.getCid(), sessionKey); | |
keys.add(key); | |
} | |
} catch (Exception e) { | |
throw new KomandorException(e); | |
} | |
return keys; | |
} | |
private static SecretKey generateKeyAgreement(PrivateKey pk, X509Certificate partnerCert, byte[] sv) throws NoSuchProviderException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException { | |
final IvParameterSpec ivspec = new IvParameterSpec(sv); | |
final KeyAgreement keyAgree = KeyAgreement.getInstance(pk.getAlgorithm(), JCSP.PROVIDER_NAME); | |
keyAgree.init(pk, ivspec, null); | |
keyAgree.doPhase(partnerCert.getPublicKey(), true); | |
return keyAgree.generateSecret(CIPHER_ALG); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment