I'm trying to decrypt the payload of a tcp package.
I'm given a key, which is a string of 64 characters, looks like a hex stream, and a "password" (string 8 chars).
I'm told that the encryption algorithm is probably AES.
That's all information given :)
I have tried a few online decryption tools but the results are not understandable.
Do I have enough information to properly decrypt this?
How do I properly convert the 64 bytes string to a key
If anyone would point me in a direction on how to do this in .NET that would be highly appreciated :)
Related
I have been working to create an RTP/RTCP client and server implementation as a project. I have hit a block when it comes to parsing incoming packets because I am having trouble understanding the encryption method. I have read RFC 3550 several times. Section 9 explains confidentiality and security. I've read about DES-CBC mode here.
Observations I've deduced about encryption
RTP/RTCP packets are encrypted as a unit, meaning ALL bytes are encrypted
Encrypted RTCP packets are prefixed with a 32-bit random number
Encrypted RTP packets are randomized by the timestamp and sequence number
DES-CBC is the default mode
DES-CBC mode requires a 64-bit key
DES-CBC mode requires a 64-bit initialization vector (IV)
DES-CBC has a block size of 64 bits
What I'm confused about:
DES-CBC states that it uses the "Privacy Enhancement for Internet Electronic Mail" (PEM) protocol, but the RTP RFC makes no mention of this. In addition, the encryption diagrams do not include any PEM headers or elements.
Diagram
UDP packet UDP packet
----------------------------- ------------------------------
[random][RR][SDES #CNAME ...] [SR #senderinfo #site1 #site2]
----------------------------- ------------------------------
encrypted not encrypted
So my questions are:
Where does the key come from or what header elements make up the key?
What is the initialization vector for RTP/RTCP?
How do I parse an encrypted packet vs an unencrypted one?
Does RTP/RTCP use the PEM protocol? If so, how?
DES-CBC is a way for encrypting data and it can be used for all different protocols that need it's data to be encrypted.
Where does the key come from or what header elements make up the key?
Encryption keys are generated during connection initialization(at connect time) and can be generated using different ways but generally using Public key cryptography(ex: RSA and DH) and using certificates to prevent MITM attacks which is where the PEM standards are used.
What is the initialization vector for RTP/RTCP?
The IV(initialization vector) is randomly generated number that will be used to ensure that same plaintext will not be encrypted to same ciphertext if using same key (That's why it's Random).
How do I parse an encrypted packet vs an unencrypted one?
For encrypted packets you decrypt first using key(SECRET) you got at connection time then use IV which is sent with data packets(NOT secret) to reverse encryption process. For unencrypted packets you just parse the data since there is no KEY and IV data is just plaintext.
Does RTP/RTCP use the PEM protocol? If so, how?
PEM is not protocol in the sense as network protocols such SSH. This definition I think is accurate enough from wikipedia
Privacy-Enhanced Mail (PEM) is a de facto file format for storing and sending cryptographic keys, certificates, and other data, based on a set of 1993 IETF standards defining "privacy-enhanced mail.
so if your client is using encryption there is a very big chance that it will be using PEM standards for symmetric key initialization.
NOTE: timestamp and sequence number are different from IV these fields are RTP header fields which can serve a similar purpose but they are different from CBC mode IV.
I tried to understand how the implementation of srtp on the linphone application. When I activate the srtp feature on the phone, the digital data communication will be secured using the AES-ICM encryption method. But I found something interesting in its implementation.
The encryption process in the AES-ICM method works with xor operations between keystream suffix and RTP packet payload (plaintext) to produce ciphertext. The encryption key is used in an aes operation to generate a suffix keystream. This ciphertext will then be sent from the sender to the receiver.
In the implementation of SRTP, I display the plaintext, key and ciphertext used or generated by the sender and receiver. I found the difference between the ciphertext and key for each packet in the sender and receiver. When a plaintext is encrypted using a specific key and produces a ciphertext in the sender, the receiver, the ciphertext that is received and the key that is used has a difference. However, the strange thing that I found was that the results of the decryption of the plaintext on the receiver are the same plaintext as what is encrypted in the sender. And the voice that was communicated arrived, can anyone explain this why?
Code to display text : https://pastelink.net/1re6m
Log endpoint 1 : https://pastelink.net/1re93
Log endpoint 2 : https://pastelink.net/1re9c
Then, I tried to deactivate the encryption feature by using the srtp_cipher_encrypt code in the srtp_protect_mki and srtp_cipher_decrypt modules in the srtp_unprotect_mki module. Isn't that as if it didn't encrypt the payload like the Null Cipher is implemented? However, the same ones found are ciphertext and plaintext that have nothing in common with the sender and receiver as well as the sound on the speakers that contain noise without being able to identify what is being sent. Can anyone explain this too?
For example, the first plaintext used for encryption at endpoint one is:
"d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d ......"
generate ciphertext:
"7c8fb6c2f783e5fdb34116bb5d5ce27475bf400b4 ........"
then at endpoint 2 which acts as a receiver, the first ciphertext received is
"e2bd90a5275e44ac2d4fc332cfff138e743c39c80b ......."
generate plaintext:
"d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5 ......."
Thank you
I find the answer from another forum. In my case this is happening because the VOIP server which is I am using Asterisk will decrypt every incoming packet for processing before sending it back. This package will then be re-encrypted by Asterisk before being sent to its final destination. Every packet that enters will be decrypted and the one that exits the asterisk will be re-encrypted. So, in my case, this happened because of the voip server technology used.
I'm expecting to cipher a string, from a client side (using aes-256-cbc and a Secret-Password already known by both server & client).
And then I'd like to decipher it (on the server side).
I have a code which does work just fine (functionnaly speaking). But it seems I need to send the IV vector from client to server.
I currently did it like this :
00000000000000000000000000000000.JAPQElUAxxxxxxxxxxxjTgJAPQElUAfgydvbY=
So, on the server I split the payload with a "dot" as separator and consider the first item to be the vector.
I believe this is not good to sendthe IV like this.
Would you please help me to understand how should it works?
In CBC encryption mode sending the IV without encrypted is normal and there is nothing to worry as long as the IV is unpredictable. See this question Why is CBC with predictable IV considered insecure against chosen-plaintext attack? from Cryptography.
A common way to send the IV is prepending it to the ciphertext. The libraries, in general, were designed to extract first 16-byte or enable offset in the byte-arrays.
CBC mode of operation is outdated. It has many problems as padding oracled attacks. You should use better alternative Authenticated Encryption (AE) modes as AES-GCM and ChaCha-Poly1305 which does not need padding. Also, in AE you will have confidentiality, integrity, and authentication where CBC only supports confidentiality.
AS modes provide an Authentication Tag that you will need to transmit with the IV. The usual practice; prepend the IV and append the tag to the ciphertext.
IV || Ciphertext||Tag
i try to use chacha20 encryption in my network software but i encounter a problem
if i encrypt 4 bytes data: 0x01 0x02 0x03 0x04 on server
and get the ciphertext: 0xd2 0xd3 0xc4 0xd5, then send it to client
the client may receive <= 4bytes at a time
provided that client only recv 0xd2 0xd3 at first ,
it can decrypt data properly and get plaintext 0x01 0x02
but when client recv the last 2 bytes 0xc4 0xd5
it seems that the data can't be decrypt using the same nonce and key
so is there a way to solve the problem
adding length data as prefix before sending is a solution,but it's weird because i am using stream cipher.
Instead of restarting the ChaCha20 cipher instance (or, more generically, context) you should keep it alive.
Most cryptographic API's will allow you to perform piecemeal encryption / decryption. That usually means calling an update method for the first part and second part, generally followed by a final method when the end of the plaintext / ciphertext is detected. Depending on the API you should expect output for each of these methods.
Only if your API doesn't allow you to handle the stream correctly then you should aggregate the ciphertext and perform the decryption on the full ciphertext.
ChaCha20 generates a stream, using the key and the nonce. Let (S0, S1, S2, S3) the first bytes of the stream, and (M0, M1, M2, M3) the first 4 bytes of your message.
The ciphertext will be computed as (M0⊕S0, M1⊕S1, M2⊕S2, M3⊕S3). This is if you have M0...M3 readily available.
If you encrypt (M0, M1) then (M2, M3) using the same key and nonce, you will end up with (M0⊕S0, M1⊕S1) and (M2⊕S0, M3⊕S1). Which cannot be decrypted using (C0⊕S0, C1⊕S1, C2⊕S2, C3⊕S3).
Even worse, since S0 and S1 have been reused with different messages, an attacker can recover them knowing any message.
The easiest thing to do in order to avoid this is to buffer the data until you reach the block size, and then encrypt the whole block, instead of trying to encrypt partial blocks.
I am having an application where I have to send several small data per second through the network using UDP. The application needs to send the data in real-time (no waiting). I want to encrypt these data and ensure that what I am doing is as secure as possible.
Since I am using UDP, there is no way to use SSL/TLS, so I have to encrypt each packet alone since the protocol is connectionless/unreliable/unregulated.
Right now, I am using a 128-bit key derived from a passphrase from the user, and AES in CBC mode (PBE using AES-CBC). I decided to use a random salt with the passphrase to derive the 128-bit key (prevent dictionary attack on the passphrase), and of course use IVs (to prevent statistical analysis for packets).
However I am concerned about few things:
Each packet contains small amount of data (like a couple of integer values per packet) which will make the encrypted packets vulnerable to known-plaintext attacks (which will result in making it easier to crack the key). Also, since the encryption key is derived from a passphrase, this will make the key space way smaller (I know the salt will help, but I have to send the salt through the network once and anyone can get it). Given these two things, anyone can sniff and store the sent data, and try to crack the key. Although this process might take some time, once the key is cracked all the stored data will be decrypted, which will be a real problem for my application.
So my question is, what are the best practices for sending/encrypting continuous small data using a connectionless protocol (UDP)?
Is my way the best way to do it? ...flowed? ...Overkill?
Please note that I am not asking for a 100% secure solution, as there is no such thing.
You have several choices. You can use DTLS, which is a version of TLS adapated for datagrams. It is specified in an RFC and implemented in the openssl library. You can also use the IKE/IPsec protocol and use a UDP encapsulation of the IPsec portion. Usually IPsec is available at the OS level. You can also use OpenVPN, which looks to be a hybrid of TLS for key exchange and a proprietary UDP-based packet encryption protocol.
If your problem is that the data is too small, how about extending the data with random bytes? This will make the plaintext much harder to guess.
This question is a little old, but what about using a One Time Pad type approach? You could use a secure reliable transport mechanism (like HTTPS) to transmit the one time keys from the server to your client. There could be two sets of keys -- one for client to sever, and one for server to client. Each datagram would then include a sequence number (used to identify the one time key) and then the encrypted message. Because each key is used for only one datagram, you shouldn't be exposed to the small data problem. That said, I'm not an expert at this stuff, so definitely check this idea out before using it...
Use Ecdh key exchange (use a password to encrypt the client private key; left on the client) instead of a password. This is a very strong key.
Aes cbc does not help you; the messages are too short and you want to prevent replay attacks. Pad your 64 bit message (two integers) with a counter (starting with 0) 64 bits means 2^64 messages can be sent. Encrypt the block twice (aes ecb) and send e(k;m|count)|e(k;e(k;m|count)). Receiver only accepts monotonically increasing counts where the second block is the encryption of the first. These are 32 byte messages that fit fine in a udp packet.
if 2^64 messages is too small; see if your message could be smaller (3 byte integers means the counter can be 80 bits); or go back to step 1 (new private keys for at least one side) once you are close (say 2^64-2^32) to the limit.
You could always generate a fresh pair of IVs and send them alongside the packet.
These days a good streaming cipher is the way to go. ChaCha20 uses AES for a key stream. Block ciphers are the ones that need padding.
Still that's only part of the picture. Don't roll your own crypto. DTLS is probably a mature option. Also consider QUIC which is emerging now for general availability on the web.
Consider using ECIES Stateless Encryption https://cryptopp.com/wiki/Elliptic_Curve_Integrated_Encryption_Scheme where you sending devices use the public key of the central system and an ephemeral key to generate a symmetric key pair, then a KDF, then AES-256-GCM. You end up with modest size packets which are stateless and complete. No need for an out-of-band key agreement protocol.
There are good examples on the internet, for example: https://github.com/insanum/ecies/blob/master/ecies_openssl.c
I am using such a system to deliver telemetry from mobile devices over an unsecure channel.