public Exchange(Self localIdentity, byte csid, byte[] publicKey) { Local = localIdentity; cipherSet = localIdentity.CipherSets [csid]; var ri = new CS1ARemoteInfo(); ri.RemotePublicKey = publicKey; cipherSet.GenerateEphemeralKeys(ri); remoteInfo = ri; var idKey = localIdentity.CipherSets [csid].Keys.PublicKey; for (int i = 0; i < publicKey.Length; ++i) { if (publicKey [i] == idKey [i]) { continue; } if (publicKey [i] > idKey [i]) { Order = HashOrder.High; At = 1; break; } else { Order = HashOrder.Low; At = 2; break; } } }
public Exchange (Self localIdentity, byte csid, byte[] publicKey) { Local = localIdentity; cipherSet = localIdentity.CipherSets [csid]; var ri = new CS1ARemoteInfo (); ri.RemotePublicKey = publicKey; cipherSet.GenerateEphemeralKeys (ri); remoteInfo = ri; var idKey = localIdentity.CipherSets [csid].Keys.PublicKey; for (int i = 0; i < publicKey.Length; ++i) { if (publicKey [i] == idKey [i]) { continue; } if (publicKey [i] > idKey [i]) { Order = HashOrder.High; At = 1; break; } else { Order = HashOrder.Low; At = 2; break; } } }
public void GenerateEphemeralKeys(ICipherSetRemoteInfo remoteInfo) { CS1ARemoteInfo ri = (CS1ARemoteInfo)remoteInfo; ri.EphemeralKeys = ECKeyPair.Generate(SecNamedCurves.GetByName("secp160r1")); var hashToken = Helpers.SHA256Hash(ri.EphemeralKeys.PublicKey.Take(16).ToArray()); ri.Token = hashToken.Take(16).ToArray(); }
public bool MessageVerify(ICipherSetRemoteInfo remoteInfo, Packet outer) { CS1ARemoteInfo ri = (CS1ARemoteInfo)remoteInfo; byte[] ivData = outer.Body.Skip(21).Take(4).ToArray(); byte[] hmacData = outer.Body.Skip(outer.Body.Length - 4).Take(4).ToArray(); // Check the hmac to validate the packet var agreedHMacKeyData = Helpers.ToByteArray(ECDHAgree(ri.RemotePublicKey, Key.PrivateKey), 20); byte[] hmacKey = new byte[24]; if (agreedHMacKeyData.Length != 20) { // It's not a correct agreed value, expected 20 bytes return(false); } Buffer.BlockCopy(agreedHMacKeyData, 0, hmacKey, 0, 20); Buffer.BlockCopy(ivData, 0, hmacKey, 20, 4); var hmac = new HMac(new Sha256Digest()); byte[] fullIv = new byte[16]; Array.Clear(fullIv, 0, 16); Buffer.BlockCopy(ivData, 0, fullIv, 0, 4); hmac.Init(new KeyParameter(hmacKey, 0, 24)); hmac.BlockUpdate(outer.Body, 0, outer.Body.Length - 4); byte[] mac = new byte[hmac.GetMacSize()]; hmac.DoFinal(mac, 0); var macValue = Helpers.Fold(mac, 3); if (!macValue.SequenceEqual(hmacData)) { // The hmacs did not match, blow up the world return(false); } return(true); }
public void Handshake() { byte[] A_KEY = Telehash.Base32Encoder.Decode("anfpjrveyyloypswpqzlfkjpwynahohffy"); byte[] A_SEC = Telehash.Base32Encoder.Decode("cgcsbs7yphotlb5fxls5ogy2lrc7yxbg"); byte[] B_KEY = Telehash.Base32Encoder.Decode("amhofcnwgmolf3owg2kipr5vus7uifydsy"); byte[] B_SEC = Telehash.Base32Encoder.Decode("ge4i7h3jln4kltngwftg2yqtjjvemerw"); Self localSelf = new Self (); CipherSet1a cs = new CipherSet1a (); cs.LoadKeys (A_KEY, A_SEC); localSelf.CipherSets.Add(0x1a, cs); Exchange ex = new Exchange (localSelf, 0x1a, B_KEY); var outPacket = ex.Handshake (0x1a); Console.Write (outPacket); Self remoteSelf = new Self (); CipherSet1a remoteCs = new CipherSet1a (); remoteCs.LoadKeys (B_KEY, B_SEC); remoteSelf.CipherSets.Add (0x1a, remoteCs); CS1ARemoteInfo ri = new CS1ARemoteInfo (); ri.RemotePublicKey = A_KEY; var decryptedPacket = remoteCs.MessageDecrypt (outPacket); System.Diagnostics.Debug.Write (decryptedPacket); }
public Packet MessageEncrypt(ICipherSetRemoteInfo remoteInfo, Packet inner) { CS1ARemoteInfo ri = (CS1ARemoteInfo)remoteInfo; var agreedValue = ECDHAgree(ri.RemotePublicKey, ri.EphemeralKeys.PrivateKey); // Hash the agreed key var hashedValue = Helpers.SHA256Hash(Helpers.ToByteArray(agreedValue, 20)); // Fold to get the actual key for AES byte[] aesKey = Helpers.Fold(hashedValue); Random rnd = new Random(); // Setup and encrypt the actual data byte[] aesIV = new byte[16]; rnd.NextBytes(aesIV); Array.Clear(aesIV, 4, 12); var cipher = new SicBlockCipher(new AesFastEngine()); var parameters = new ParametersWithIV(new KeyParameter(aesKey), aesIV); cipher.Init(true, parameters); var encryptedInner = new byte[inner.FullPacket.Length]; BufferedBlockCipher bufferCipher = new BufferedBlockCipher(cipher); var offset = bufferCipher.ProcessBytes(inner.FullPacket, encryptedInner, 0); bufferCipher.DoFinal(encryptedInner, offset); // Construct the packet minus the hmac Packet outPacket = new Packet(); outPacket.Body = new byte[29 + encryptedInner.Length]; Buffer.BlockCopy(ri.EphemeralKeys.PublicKey, 0, outPacket.Body, 0, ri.EphemeralKeys.PublicKey.Length); Buffer.BlockCopy(aesIV, 0, outPacket.Body, 21, 4); Buffer.BlockCopy(encryptedInner, 0, outPacket.Body, 25, encryptedInner.Length); // ECDH for the hmac key using var idAgreedValue = ECDHAgree(ri.RemotePublicKey, Key.PrivateKey); // Mash on the IV for the compound key byte[] macKey = new byte[24]; byte[] idAgreedValueArray = Helpers.ToByteArray(idAgreedValue, 20); Buffer.BlockCopy(idAgreedValueArray, 0, macKey, 0, idAgreedValueArray.Length); Buffer.BlockCopy(aesIV, 0, macKey, idAgreedValueArray.Length, 4); // Actually hmac all the data now var hmac = new HMac(new Sha256Digest()); hmac.Init(new KeyParameter(macKey, 0, 24)); hmac.BlockUpdate(outPacket.Body, 0, 25 + encryptedInner.Length); byte[] mac = new byte[hmac.GetMacSize()]; hmac.DoFinal(mac, 0); // Fold it up, shove it in and we're done var foldedMac = Helpers.Fold(mac, 3); Buffer.BlockCopy(foldedMac, 0, outPacket.Body, 25 + encryptedInner.Length, foldedMac.Length); return(outPacket); }