private static void ComputeAesKeyAndIV(byte[] authKey, Int128 msgKey, out byte[] aesKey, out byte[] aesIV, IHashServices hashServices, Sender sender) { // x = 0 for messages from client to server and x = 8 for those from server to client. int x; switch (sender) { case Sender.Client: x = 0; break; case Sender.Server: x = 8; break; default: throw new ArgumentOutOfRangeException("sender"); } byte[] msgKeyBytes = msgKey.ToBytes(); byte[] buffer = _aesKeyAndIVComputationBuffer ?? (_aesKeyAndIVComputationBuffer = new byte[32 + MsgKeyLength]); // sha1_a = SHA1 (msg_key + substr (auth_key, x, 32)); Buffer.BlockCopy(msgKeyBytes, 0, buffer, 0, MsgKeyLength); Buffer.BlockCopy(authKey, x, buffer, MsgKeyLength, 32); byte[] sha1A = hashServices.ComputeSHA1(buffer); // sha1_b = SHA1 (substr (auth_key, 32+x, 16) + msg_key + substr (auth_key, 48+x, 16)); Buffer.BlockCopy(authKey, 32 + x, buffer, 0, 16); Buffer.BlockCopy(msgKeyBytes, 0, buffer, 16, MsgKeyLength); Buffer.BlockCopy(authKey, 48 + x, buffer, 16 + MsgKeyLength, 16); byte[] sha1B = hashServices.ComputeSHA1(buffer); // sha1_с = SHA1 (substr (auth_key, 64+x, 32) + msg_key); Buffer.BlockCopy(authKey, 64 + x, buffer, 0, 32); Buffer.BlockCopy(msgKeyBytes, 0, buffer, 32, MsgKeyLength); byte[] sha1C = hashServices.ComputeSHA1(buffer); // sha1_d = SHA1 (msg_key + substr (auth_key, 96+x, 32)); Buffer.BlockCopy(msgKeyBytes, 0, buffer, 0, MsgKeyLength); Buffer.BlockCopy(authKey, 96 + x, buffer, MsgKeyLength, 32); byte[] sha1D = hashServices.ComputeSHA1(buffer); // aes_key = substr (sha1_a, 0, 8) + substr (sha1_b, 8, 12) + substr (sha1_c, 4, 12); aesKey = new byte[32]; Buffer.BlockCopy(sha1A, 0, aesKey, 0, 8); Buffer.BlockCopy(sha1B, 8, aesKey, 8, 12); Buffer.BlockCopy(sha1C, 4, aesKey, 20, 12); // aes_iv = substr (sha1_a, 8, 12) + substr (sha1_b, 0, 8) + substr (sha1_c, 16, 4) + substr (sha1_d, 0, 8); aesIV = new byte[32]; Buffer.BlockCopy(sha1A, 8, aesIV, 0, 12); Buffer.BlockCopy(sha1B, 0, aesIV, 12, 8); Buffer.BlockCopy(sha1C, 16, aesIV, 20, 4); Buffer.BlockCopy(sha1D, 0, aesIV, 24, 8); }
/// <summary> /// Calculates fingerprint for a public RSA key. /// </summary> /// <param name="keyData">Bare serialized type of a constructor: "rsa_public_key n:string e:string = RSAPublicKey".</param> /// <returns>Returns fingerprint as lower 64 bits of the SHA1(RSAPublicKey).</returns> public ulong ComputeFingerprint(byte[] keyData) { byte[] hash = _hashServices.ComputeSHA1(keyData); return(hash.ToUInt64(hash.Length - 8)); }
private byte[] ComputeSHA1(byte[] data) { return(_hashServices.ComputeSHA1(data)); }
private ulong ComputeAuthKeyId(byte[] authKey, IHashServices hashServices) { byte[] authKeySHA1 = hashServices.ComputeSHA1(authKey); return(authKeySHA1.ToUInt64(authKeySHA1.Length - 8, true)); }
private static Int128 ComputeMsgKey(ArraySegment <byte> bytes, [NotNull] IHashServices hashServices) { byte[] innerDataSHA1 = hashServices.ComputeSHA1(bytes); return(innerDataSHA1.ToInt128(innerDataSHA1.Length - 16, true)); }