public void SaveKey(string path) { byte[] data = CryptoUtil.SerializeKey(privateKey); File.WriteAllBytes(path, data); }
public byte[] ExportKey() { return(CryptoUtil.SerializeKey(privateKey)); }
// unicast/broadcast // () asymmetric encrypt // <[sender hash][recipient hash]([sender hash][message])[signature]> // [32 ][32 ] [32 ][msg len] [256 ] // // multicast // () symmetric encrypt // <[sender hash][recipient hash][IV](<[message][signature]>)[signature]> public BroadcastMessageDto EncodePacket(byte[] message, byte[] remoteKey = null) { if (remoteKey != null && remoteKey.Length != CryptoUtil.ASYM_KEY_SIZE_BYTES && remoteKey.Length != CryptoUtil.SYM_KEY_SIZE) { throw new CryptographicException("Bad key size"); } byte[] senderHash = CryptoUtil.GetHash(privateKey.Modulus); byte[] recipientHash = CryptoUtil.GetHash(remoteKey);; byte[] processedMessage; if (remoteKey == null) { // broadcast recipientHash = BROADCAST_ID; processedMessage = message; } else if (remoteKey.Length == CryptoUtil.ASYM_KEY_SIZE_BYTES) { // unicast using (var ms = new MemoryStream()) using (var writer = new BinaryWriter(ms)) { writer.Write(senderHash); writer.Write(message); processedMessage = ms.ToArray(); } processedMessage = CryptoUtil.AsymmetricEncrypt(processedMessage, remoteKey); } else { // multicast using (var ms = new MemoryStream()) using (var writer = new BinaryWriter(ms)) { writer.Write(message); writer.Write(CryptoUtil.Sign(message, privateKey)); processedMessage = ms.ToArray(); } byte[] iv = CryptoUtil.GenerateIV(); processedMessage = CryptoUtil.SymmetricEncrypt(processedMessage, remoteKey, iv); using (var ms = new MemoryStream()) using (var writer = new BinaryWriter(ms)) { writer.Write(iv); writer.Write(processedMessage); processedMessage = ms.ToArray(); } } byte[] payload; using (var ms = new MemoryStream()) using (var writer = new BinaryWriter(ms)) { writer.Write(senderHash); writer.Write(recipientHash); writer.Write(processedMessage); payload = ms.ToArray(); } byte[] signature = CryptoUtil.Sign(payload, privateKey); return(new BroadcastMessageDto { SourceIdHash = senderHash, DestinationIdHash = recipientHash, Payload = processedMessage, Signature = signature }); }
public bool TryDecodePayload(BroadcastMessageDto broadcastMessage, out byte[] decryptedPayload) { var senderHash = broadcastMessage.SourceIdHash; var receiverHash = broadcastMessage.DestinationIdHash; var payload = broadcastMessage.Payload; var signature = broadcastMessage.Signature; byte[] totalMessage; using (var ms = new MemoryStream()) using (var writer = new BinaryWriter(ms)) { writer.Write(senderHash); writer.Write(receiverHash); writer.Write(payload); totalMessage = ms.ToArray(); } var senderNode = identityManager.LookupIdentity(senderHash); if (senderNode == null) { // throw new InvalidStateException("Sender has not recognized"); decryptedPayload = null; return(false); } if (!CryptoUtil.Verify(totalMessage, senderNode.ThisId, signature)) { // throw new CryptographicException("Could not verify message"); decryptedPayload = null; return(false); } // message is now verified byte[] symmetricKey; if (receiverHash.SequenceEqual(BROADCAST_ID)) { // broadcast decryptedPayload = payload; return(true); } else if (receiverHash.SequenceEqual(identityHash)) { // unicast to us var decryptedSenderAndMessage = CryptoUtil.AsymmetricDecrypt(payload, privateKey); if (!decryptedSenderAndMessage.Take(CryptoUtil.HASH_SIZE).SequenceEqual(senderHash)) { // BREACH BREACH BREACH DEPLOY SECURITY COUNTER MEASURES // throw new CryptographicException("DATA WAS BAD THERE ARE BAD PEOPLE HERE THEY MUST BE KEPT OUT"); decryptedPayload = null; return(false); } decryptedPayload = decryptedSenderAndMessage.Skip(CryptoUtil.HASH_SIZE).ToArray(); return(true); } else if (identityManager.TryLookupMulticastKey(IdentityHash.GetFlyweight(receiverHash), out symmetricKey)) { // multicast var iv = payload.Take(CryptoUtil.IV_SIZE).ToArray(); var encryptedMessage = payload.Skip(CryptoUtil.IV_SIZE).ToArray(); var messageAndInnerSignature = CryptoUtil.SymmetricDecrypt(encryptedMessage, symmetricKey, iv); var innerSignature = messageAndInnerSignature.Skip(messageAndInnerSignature.Length - CryptoUtil.ASYM_KEY_SIZE_BYTES).ToArray(); var message = messageAndInnerSignature.Take(messageAndInnerSignature.Length - CryptoUtil.ASYM_KEY_SIZE_BYTES).ToArray(); if (!CryptoUtil.Verify(message, senderNode.ThisId, innerSignature)) { // throw new CryptographicException("Could not verify inner signature"); decryptedPayload = null; return(false); } decryptedPayload = message; return(true); } else { // unknown multi/unicast decryptedPayload = null; return(false); } }
// validates this node's signature public bool ValidateSignature() { return(CryptoUtil.Verify(Payload, ParentId, ParentSignature)); }