I am using this Arduino library and this Android library to:
Create random string in Arduino
Pass it to Android to encrypt with AES and shared secret key
Pass back to Arduino to decrypt with AES and shared secret key
Verify that original random string matches decrypted string
I'm am using AES 128bit in both devices and CBC and can get them to encrypt and decrypt their own strings, but I'm having trouble tying them together. I've got a few questions that will hopefully help:
How do the "blocks" in the Arduino code relate to the Android
implementation?
From what I've read, to decrypt the cipher text on the Arduino from
Android I will need to send, the cipher text, the IV, and the PBE
iteration count. Is that correct and everything?
Android code takes my key and uses a bunch of SecretKeys functions
on it to I think randomize it and make it more secure. If I'm having
to store the key on the Arduino, do I need to even bother with this?
Where is the PBE iteration count in the Arduino code? I don't really
see anything in the library. Do I need to implement that myself? I
saw in the "test_vectors" example of the library a section that had
the following bit of code. Is this the iteration?
for (int j = 0 ; j < 1000 ; j++)
{
succ = aes.encrypt (plain, cipher) ;
aes.copy_n_bytes (plain, cipher, 16) ;
}
Related
I ran into an issue with my server that made me ask a question - is AES-256 encryption reliably consistent?
So my node server, to avoid DDOS vulnerabilities while keeping user data anonymous, takes an IP from the request, encrypts it, and stores the number of times it has made a request in the last 24 hours.
It checks if the user had made a request in the last 24 hours by re-encrypting the IP using the exact same password. It then, takes that and matches it with the first stored IP.
But then:
Error: Can't find data: /ipcount/d00c526612cec9e5d3e201af35993c75. Stopped at ipcount
d00c526612cec9e5d3e201af35993c75 should be the encrypted string, but the database is acting like it's never seen it before. So can I have it encrypt consistently with the same password?
Thanks in advance.
Here is the encryption function...
const crypto = require('crypto'),
algorithm = 'aes-256-ctr',
password = 'aSecureNotSharedOverAForumPassword'
function encrypt(text){
var cipher = crypto.createCipher(algorithm,password)
var crypted = cipher.update(text,'utf8','hex')
crypted += cipher.final('hex');
return crypted;
}
As per the Node.js documentation for crypto:
It is recommended that developers derive a key and IV on their own using crypto.pbkdf2() and to use crypto.createCipheriv() to create the Cipher object. Users should not use ciphers with counter mode (e.g. CTR, GCM or CCM) in crypto.createCipher()
So the behaviour you are experiencing isn't exactly a defined behaviour, per se. My guess is that the underlying cipher object is randomly generating a nonce for your CTR mode and thus the output is different each time.
To fix this, use crypto.createCipheriv as recommended by the documentation and generate the nonce yourself. This way you can store the nonce and use it to generate the same output stream.
For others who are looking, do not use the same nonce. It takes away all the security guarantees of AES. Take a look at this thread instead: CryptoJS AES encryption with ECB mode produces different results with the same params
my goal is to encrypt iBeacon data (UUID+MajorID+MinorID: 20 bytes), preferably with a timestamp included (encrypted and plain), thus summing up to around 31/32 bytes.
As you have already found out, this exceeds the maximum allowed iBeacon Data (31 bytes, including iBeacon prefix and tx power).
Thus, encryption only works by creating a custom beacon format instead of the iBeacon format?
Talking about encryption: I would think about using a symmetrical cipher using CBC operation mode (to avoid decipher due to repetition, and most important to avoid cipher text adjustments resulting in a changed UUID, Major-/MinorID). It's not problem to make the IV (Initialization Vector) public (unencrypted), right?
Remember, the iBeacons work in advertising mode (transfer only), without being connected to beforehand, thus I am not able to exchange an initialization vector (IV) before any data is sent.
Which considerations should be made using the most appropriate cipher algorithm? Is AES-128 OK? With or without padding-scheme? I also thought about a AES-GCM constellation, but I don't this it's really necessary/applicable due to the used advertising mode. How should I exchange session tokens? Moreover, there's no real session in my case, the iBeacons send data 24/7, open end, without a real initialization of a connection.
Suppose a system containing of 100 iBeacons, 20 devices and 1 application. Each iBeacon sends data periodically (i.e. 500ms), being received by near devices via BLE, that forward the data to an application via udp.
So the system overview relation is:
n iBeacons -(ble)- k devices -(udp)- 1 Application
Is it acceptable to use the same encryption key on each iBeacon? If I would work with a tuple (iBeacon Id / encryption key), i would additionally have to add the iBeacon Id to each packet, thus being able to lookup the key in a dictionary.
Should the data be decrypted on the device or only later in the application?
You can look at the Eddystone-EID spec to see how Google tried to solve a similar problem.
I'm not an expert on all the issues you bring up, but I think Google offers a good solution for your first question: how can you get your encrypted payload to fit in the small number of bytes available to a beacon packet?
Their answer is: you don't. They solve this problem by truncating the encrypted payload to make a hash, and then using an online service to "resolve" this hash and see if it matches any of your beacons. The online service simply performs the same hashing algorithm against every beacon you have registered, and see if it comes up with the same value for the time period. If so, it can convert the encrypted hash identifier into a useful one.
Before you go too far with this approach, be sure to consider #Paulw11's point that on iOS devices you can must know the 16-byte iBeacon UUID up front or the operating system blocks you from reading the rest of the packet. For this reason, you may have to stick with the Android platform if using iBeacon, or switch to the similar AltBeacon format that does not have this restriction on iOS.
thanks for your excellent post, I hadn't heard about the Eddystone spec before, it's really something to look into, and it has a maximum payload length of 31 bytes, just like iBeacon. In the paper it is written that in general, it is an encryption of a timestamp value (since a pre-defined epoch). Did I get the processing steps right?
Define secret keys (EIKs) for each beacon and share those keys with another resolver or server (if there's a constellation without a online resource);
Create lookup tables on the server with a PRF (like AES CTR);
Encrypt timestamp on beacon with PRF(i.e. AES CTR?) and send data in Eddystone format to resolver/server;
Server compares received ciphertext with entries in lookup table, thus knows about the beacon id, because each beacon has a unique secret key, which leads to a different ciphertext
Would it work the same way with AES-EAX? All I'd have to put into the algorithm is an IV(nonce value) as well as the key and message? The other end would build the same tuple to compare ciphertext and tag'?
Question: What about the IRK (identity resolution key), what is it? Which nonce would be used for AES CTR? Would each beacon use the same nonce? It has to be known to the resolver/server, too.
What about time synchronization? There's no real connection between beacon and resolver/server, but is it assumed that both ends are synchronized with the same time server? Or how should beacon and resolver/server get the same ciphertext, if one end works in the year 2011, while the resolver has arrived in 2017?
For
`BDK = "0123456789ABCDEFFEDCBA9876543210"` `KSN = "FFFF9876543210E00008"`
The ciphertext generated was below
"C25C1D1197D31CAA87285D59A892047426D9182EC11353C051ADD6D0F072A6CB3436560B3071FC1FD11D9F7E74886742D9BEE0CFD1EA1064C213BB55278B2F12"`
which I found here. I know this cipher-text is based on BDK and KSN but how this 128 length cipher text was generated? What are steps involved in it or algorithm used for this? Could someone explain in simple steps. I found it hard to understand the documents I got while googled.
Regarding DUKPT , there are some explanations given on Wiki. If that doesn't suffice you, here goes some brief explanation.
Quoting http://www.maravis.com/library/derived-unique-key-per-transaction-dukpt/
What is DUKPT?
Derived Unique Key Per Transaction (DUKPT) is a key management scheme. It uses one time encryption keys that are derived from a secret master key that is shared by the entity (or device) that encrypts and the entity (or device) that decrypts the data.
Why DUKPT?
Any encryption algorithm is only as secure as its keys. The strongest algorithm is useless if the keys used to encrypt the data with the algorithm are not secure. This is like locking your door with the biggest and strongest lock, but if you hid the key under the doormat, the lock itself is useless. When we talk about encryption, we also need to keep in mind that the data has to be decrypted at the other end.
Typically, the weakest link in any encryption scheme is the sharing of the keys between the encrypting and decrypting parties. DUKPT is an attempt to ensure that both the parties can encrypt and decrypt data without having to pass the encryption/decryption keys around.
The Cryptographic Best Practices document that VISA has published also recommends the use of DUKPT for PCI DSS compliance.
How DUKPT Works
DUKPT uses one time keys that are generated for every transaction and then discarded. The advantage is that if one of these keys is compromised, only one transaction will be compromised. With DUKPT, the originating (say, a Pin Entry Device or PED) and the receiving (processor, gateway, etc) parties share a key. This key is not actually used for encryption. Instead, another one time key that is derived from this master key is used for encrypting and decrypting the data. It is important to note that the master key should not be recoverable from the derived one time key.
To decrypt data, the receiving end has to know which master key was used to generate the one time key. This means that the receiving end has to store and keep track of a master key for each device. This can be a lot of work for someone that supports a lot of devices. A better way is required to deal with this.
This is how it works in real-life: The receiver has a master key called the Base Derivation Key (BDK). The BDK is supposed to be secret and will never be shared with anyone. This key is used to generate keys called the Initial Pin Encryption Key (IPEK). From this a set of keys called Future Keys is generated and the IPEK discarded. Each of the Future keys is embedded into a PED by the device manufacturer, with whom these are shared. This additional derivation step means that the receiver does not have to keep track of each and every key that goes into the PEDs. They can be re-generated when required.
The receiver shares the Future keys with the PED manufacturer, who embeds one key into each PED. If one of these keys is compromised, the PED can be rekeyed with a new Future key that is derived from the BDK, since the BDK is still safe.
Encryption and Decryption
When data needs to be sent from the PED to the receiver, the Future key within that device is used to generate a one time key and then this key is used with an encryption algorithm to encrypt the data. This data is then sent to the receiver along with the Key Serial Number (KSN) which consists of the Device ID and the device transaction counter.
Based on the KSN, the receiver then generates the IPEK and from that generates the Future Key that was used by the device and then the actual key that was used to encrypt the data. With this key, the receiver will be able to decrypt the data.
Source
First, let me quote the complete sourcecode you linked and of which you provided only 3 lines...
require 'bundler/setup'
require 'test/unit'
require 'dukpt'
class DUKPT::DecrypterTest < Test::Unit::TestCase
def test_decrypt_track_data
bdk = "0123456789ABCDEFFEDCBA9876543210"
ksn = "FFFF9876543210E00008"
ciphertext = "C25C1D1197D31CAA87285D59A892047426D9182EC11353C051ADD6D0F072A6CB3436560B3071FC1FD11D9F7E74886742D9BEE0CFD1EA1064C213BB55278B2F12"
plaintext = "%B5452300551227189^HOGAN/PAUL ^08043210000000725000000?\x00\x00\x00\x00"
decrypter = DUKPT::Decrypter.new(bdk, "cbc")
assert_equal plaintext, decrypter.decrypt(ciphertext, ksn)
end
end
Now, you're asking is how the "ciphertext" was created...
Well, first thing we know is that it is based on "plaintext", which is used in the code to verify if decryption works.
The plaintext is 0-padded - which fits the encryption that is being tested by verifying decryption with this DecrypterTest TestCase.
Let's look at the encoding code then...
I found the related encryption code at https://github.com/Shopify/dukpt/blob/master/lib/dukpt/encryption.rb.
As the DecrypterTEst uses "cbc", it becomes apparent that the encrypting uses:
#cipher_type_des = "des-cbc"
#cipher_type_tdes = "des-ede-cbc"
A bit more down that encryption code, the following solves our quest for an answer:
ciphertext = des_encrypt(...
Which shows we're indeed looking at the result of a DES encryption.
Now, DES has a block size of 64 bits. That's (64/8=) 8 bytes binary, or - as the "ciphertext" is a hex-encoded text representation of the bytes - 16 chars hex.
The "ciphertext" is 128 hex chars long, which means it holds (128 hex chars/16 hex chars=) 8 DES blocks with each 64 bits of encrypted information.
Wrapping all this up in a simple answer:
When looking at "ciphertext", you are looking at (8 blocks of) DES encrypted data, which is being represented using a human-readable, hexadecimal (2 hex chars = 1 byte) notation instead of the original binary bytes that DES encryption would produce.
As for the steps involved in "recreating" the ciphertext, I tend to tell you to simply use the relevant parts of the ruby project where you based your question upon. Simply have to look at the sourcecode. The file at "https://github.com/Shopify/dukpt/blob/master/lib/dukpt/encryption.rb" pretty much explains it all and I'm pretty sure all functionality you need can be found at the project's GitHub repository. Alternatively, you can try to recreate it yourself - using the preferred programming language of your choice. You only need to handle 2 things: DES encryption/decryption and bin-to-hex/hex-to-bin translation.
Since this is one of the first topics that come up regarding this I figured I'd share how I was able to encode the ciphertext. This is the first time I've worked with Ruby and it was specifically to work with DUKPT
First I had to get the ipek and pek (same as in the decrypt) method. Then unpack the plaintext string. Convert the unpacked string to a 72 byte array (again, forgive me if my terminology is incorrect).
I noticed in the dukpt gem author example he used the following plain text string
"%B5452300551227189^HOGAN/PAUL ^08043210000000725000000?\x00\x00\x00\x00"
I feel this string is incorrect as there shouldn't be a space after the name (AFAIK).. so it should be
"%B5452300551227189^HOGAN/PAUL^08043210000000725000000?\x00\x00\x00\x00"
All in all, this is the solution I ended up on that can encrypt a string and then decrypt it using DUKPT
class Encrypt
include DUKPT::Encryption
attr_reader :bdk
def initialize(bdk, mode=nil)
#bdk = bdk
self.cipher_mode = mode.nil? ? 'cbc' : mode
end
def encrypt(plaintext, ksn)
ipek = derive_IPEK(bdk, ksn)
pek = derive_PEK(ipek, ksn)
message = plaintext.unpack("H*").first
message = hex_string_from_unpacked(message, 72)
encrypted_cryptogram = triple_des_encrypt(pek,message).upcase
encrypted_cryptogram
end
def hex_string_from_unpacked val, bytes
val.ljust(bytes * 2, "0")
end
end
boomedukpt FFFF9876543210E00008 "%B5452300551227189^HOGAN/PAUL^08043210000000725000000?"
(my ruby gem, the KSN and the plain text string)
2542353435323330303535313232373138395e484f47414e2f5041554c5e30383034333231303030303030303732353030303030303f000000000000000000000000000000000000
(my ruby gem doing a puts on the unpacked string after calling hex_string_from_unpacked)
C25C1D1197D31CAA87285D59A892047426D9182EC11353C0B82D407291CED53DA14FB107DC0AAB9974DB6E5943735BFFE7D72062708FB389E65A38C444432A6421B7F7EDD559AF11
(my ruby gem doing a puts on the encrypted string)
%B5452300551227189^HOGAN/PAUL^08043210000000725000000?
(my ruby gem doing a puts after calling decrypt on the dukpt gem)
Look at this: https://github.com/sgbj/Dukpt.NET, I was in a similar situation where i wondered how to implement dukpt on the terminal when the terminal has its own function calls which take the INIT and KSN to create the first key, so my only problem was to make sure the INIT key was generated the same way on the terminal as it is in the above mentioned repo's code, which was simple enough using ossl encryption library for 3des with ebc and applying the appropriate masks.
So, I'm experimenting a bit with secure python programming if there is such a thing :D). This is half a real world project, and half just a training exercise. So both theory and practical advice is appreciated.
I am using an AES salted encryption script which encrypts text in the manner ...
data = "hello"
encrypted_text = encryption(data, salt_word)
print encrypted_text (responds with "huio37*\xhuws%hwj2\xkuyq\x#5tYtd\xhdtye")
plain_text = decryption(encrypted_text, salt_word)
print plain_text (responds with "hello")
QUESTION: If you know the values of "encrypted_text" and "plain_text "...can you reverse engineer the "salt_word". AND if so, how hard is it (12 seconds on a PC, or 20 years on a Cray?)
My understanding from the entire point of AES is, no you can't. But I'm just not that familiar.
I'm using an insignificantly modified version of the script here:
Encrypt / decrypt data in python with salt
Basically, it uses the "salt" to encrypt "data". salt is a string, and data comes out as a string of encrypted characters.
Using decrypt, with the same salt string, returns the data to normal text.
When you say salt with AES, what specifically are you talking about? Is this the IV to CBC or CTR mode? Is it a salt used for key generation with a passphrase (PBKDF2)?
In either case, salt's aren't usually kept secret. IV's can be transmitted in the clear, and with hashing schemes, are usually stored along with the hash (otherwise it'd be impossible to compute the hash a second time).
I've given a previous answer as to why it's safe to transmit IV's in the clear, which you can find here.
I was looking for libraries to implement an encryption system and was interested in using the NaCl: Networking and Cryptography library specifically the box function. Obviously, it uses symmetric encryption XSalsa20, Curve25519 for public-private cryptography and Poly1305 for authentication as the primitives for it.
However, the documentation looks to be insufficient in the way the they've been used. For example, it mentions that to compute the key it uses the sender's private key and the receiver's public key to compute the secret key. But it doesn't explain how. Can anyone shed any light on it?
If I were to use the same public and private key, I wouldn't the same key to be generated on the next attempt and it would be disastrous. Does anyone know of the explanation behind it or hook me up with some more documentation on how the functions work rather than how the functions can be used?
How does crypto_box work?
box uses a Diffie-Hellman key exchange on the two keys and hashes the result. Then it uses that as the key for secret_box.
crypto_box is equivalent to crypto_box_beforenm followed by crypto_box_afternm.
crypto_box_beforenm is the hashed key-exchange which works as described in the Curve25519 paper, using elliptic curve Diffie-Hellman key exchange on Curve25519 hashing the result with HSalsa. This yields a 32 byte shared key.
k = Hash(Curve25519(b, A)) = Hash(Curve25519(a, B))
crypto_box_afternm is identical to crypto_secret_box. It takes a 24 byte nonce and a 32 byte key. It's an authenticated stream cipher using XSalsa20 for encryption and Poly1305 as MAC. The first 32 bytes of the output of XSalsa20 are used for the MAC, the rest are xored into the plaintext to encrypt it.
What happens if you use it multiple times?
If you take two fixed key-pairs, the result of the key exchange will always be the same.
But the symmetric part secret_box is secure even when you use a key several times, as long as you never reuse a nonce for that key, i.e. the (key, nonce) pair must be unique.
This property is pretty much the same for all modern authenticated stream ciphers, such as AES-GCM or XSalsa20-Poly1305.
Common ways to create a unique nonce are:
Use an 8 byte prefix and a random 16 byte value (stateless, random 16 bytes are most likely unique)
Use a 16 byte prefix and a 8 byte counter (stateful, useful in a connection where you increment for each packet)
For example, it mentions that to compute the key it uses the sender's
private key and the receiver's public key to compute the secret key.
But it doesn't explain how. Can anyone shed any light on it?
There is a nice, understandable video, but in german language: https://www.youtube.com/watch?v=aC05R9xqbgE. This video explains it for both the "discrete logarithm" and the "elliptic curve" solution.
In the "elliptic curve" scenario, the public key P is a point (with x and y coordinates) on the curve. P is calculated by multiplication of a Generator G (defined by the curve) with a secret key K.To calulate the secret key S, just do a multiplication of the peer's point P (peer's public key) with the own secret key K (a scalar number). Both peers make this operation:
S_Alice = P_Bob mult K_Alice = G mult K_Bob mult K_Alice
S_Bob = P_Alice mult K_Bob = G mult K_Alice mult K_Bob
As the curve is a commutative group, the order of the multiplications does not matter, so from the above calculations you can see that in the end both Bob and Alice calculated an identical key.