示例#1
0
        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)));
        }
示例#2
0
        private StaticKeys CalculateStaticKeys(ECPublicKey staticPublic, ECPrivateKey staticPrivate, byte[] salt)
        {
            byte[]   staticSecret       = Curve.calculateAgreement(staticPublic, staticPrivate);
            byte[]   staticDerived      = new HKDFv3().deriveSecrets(staticSecret, salt, new byte[0], 96);
            byte[][] staticDerivedParts = ByteUtil.split(staticDerived, 32, 32, 32);

            return(new StaticKeys(staticDerivedParts[1], staticDerivedParts[2]));
        }
示例#3
0
        private EphemeralKeys CalculateEphemeralKeys(ECPublicKey ephemeralPublic, ECPrivateKey ephemeralPrivate, byte[] salt)
        {
            byte[]   ephemeralSecret       = Curve.calculateAgreement(ephemeralPublic, ephemeralPrivate);
            byte[]   ephemeralDerived      = new HKDFv3().deriveSecrets(ephemeralSecret, salt, new byte[0], 96);
            byte[][] ephemeralDerivedParts = ByteUtil.split(ephemeralDerived, 32, 32, 32);

            return(new EphemeralKeys(ephemeralDerivedParts[0], ephemeralDerivedParts[1], ephemeralDerivedParts[2]));
        }
示例#4
0
        private static DerivedKeys calculateDerivedKeys(byte[] masterSecret)
        {
            HKDF kdf = new HKDFv3();

            byte[]   derivedSecretBytes = kdf.deriveSecrets(masterSecret, Encoding.UTF8.GetBytes("WhisperText"), 64);
            byte[][] derivedSecrets     = ByteUtil.split(derivedSecretBytes, 32, 32);

            return(new DerivedKeys(new RootKey(kdf, derivedSecrets[0]),
                                   new ChainKey(kdf, derivedSecrets[1], 0)));
        }
示例#5
0
        public SenderMessageKey(uint iteration, byte[] seed)
        {
            byte[]   derivative = new HKDFv3().deriveSecrets(seed, Encoding.UTF8.GetBytes("WhisperGroup"), 48);
            byte[][] parts      = ByteUtil.split(derivative, 16, 32);

            this.iteration = iteration;
            this.seed      = seed;
            this.iv        = parts[0];
            this.cipherKey = parts[1];
        }
        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());
        }