Skip to content

Instantly share code, notes, and snippets.

@ReFLeXive007
Created August 7, 2019 19:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ReFLeXive007/7cf10c9edbca3550f3b3c4ad6ebc594a to your computer and use it in GitHub Desktop.
Save ReFLeXive007/7cf10c9edbca3550f3b3c4ad6ebc594a to your computer and use it in GitHub Desktop.
Сессионные ключи
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