public ProvisionMessage Decrypt(IdentityKeyPair tmpIdentity, byte[] message) { ProvisionEnvelope env = ProvisionEnvelope.Parser.ParseFrom(message); ECPublicKey publicKey = Curve.decodePoint(env.PublicKey.ToByteArray(), 0); byte[] sharedSecret = Curve.calculateAgreement(publicKey, tmpIdentity.getPrivateKey()); byte[] derivedSecret = new HKDFv3().deriveSecrets(sharedSecret, Encoding.UTF8.GetBytes("TextSecure Provisioning Message"), 64); byte[][] parts = Util.Split(derivedSecret, 32, 32); byte[] joined = env.Body.ToByteArray(); if (joined[0] != 0x01) { throw new Exception("Bad version number on provision message!"); } byte[] iv = new byte[16]; Array.Copy(joined, 1, iv, 0, 16); byte[] ciphertext = new byte[joined.Length - 32 - 17]; Array.Copy(joined, 17, ciphertext, 0, joined.Length - 32 - 17); byte[] ivAndCiphertext = new byte[joined.Length - 32]; Array.Copy(joined, ivAndCiphertext, joined.Length - 32); byte[] mac = new byte[32]; Array.Copy(joined, joined.Length - 32, mac, 0, 32); VerifyMac(parts[1], ivAndCiphertext, mac); return(ProvisionMessage.Parser.ParseFrom(Decrypt(parts[0], iv, ciphertext))); }
public byte[] encrypt(ProvisionMessage message)// throws InvalidKeyException { ECKeyPair ourKeyPair = Curve.generateKeyPair(); byte[] sharedSecret = Curve.calculateAgreement(theirPublicKey, ourKeyPair.getPrivateKey()); byte[] derivedSecret = new HKDFv3().deriveSecrets(sharedSecret, Encoding.UTF8.GetBytes("TextSecure Provisioning Message"), 64); byte[][] parts = Util.split(derivedSecret, 32, 32); byte[] version = { 0x01 }; byte[] ciphertext = getCiphertext(parts[0], message.ToByteArray()); byte[] mac = getMac(parts[1], Util.join(version, ciphertext)); byte[] body = Util.join(version, ciphertext, mac); return(ProvisionEnvelope.CreateBuilder() .SetPublicKey(ByteString.CopyFrom(ourKeyPair.getPublicKey().serialize())) .SetBody(ByteString.CopyFrom(body)) .Build() .ToByteArray()); }