2

I used CryptoSwift to encrypt some data, and then encrypted the same data using Node.js. But the results are not same. I asked the author, he said it's not a bug.

I don't know where I made a mistake. Here are pictures of how I used CryptoSwift and Node.js:

Cipher algorithm: aes-256-cfb

key: 32 bytes 1

iv: 16 bytes 0

CryptoSwift: develop-branch 0.1.1

Node.js: LTS 4.2.3

Data encrypted by CryptoSwift

Data encrypted by Node.js 4.2.3

Here is swift code:

    func testAES() {
    let key = [UInt8](count: 32, repeatedValue: 1)
    let iv = [UInt8](count: 16, repeatedValue: 0)
    print(key)
    print(iv)

    let aes256cfb = try! AES(key: key, iv: iv, blockMode: .CFB)

    let en1 = try! aes256cfb.encrypt([0x5, 0x77], padding: nil)
    print(en1.map({ i in String(format: "%2x", i)}))

    let en2 = try! aes256cfb.encrypt([0x5, 0x0, 0x3, 0x89, 0x20], padding: nil)
    print(en2.map({ i in String(format: "%2x", i)}))
}

CryptoSwift: 
["77", "ef"]
["77", "98", "c9", "2c", "45"]

Node.js: 
<Buffer 77 ef>
<Buffer cf a5 66 8a 3e>

You can see, the first two bytes are same, but the rest are not. Why? Is my code writing wrong? I don't know much about crypto, please tell me the reason. Thank you so much.

jww
  • 97,681
  • 90
  • 411
  • 885
Neko
  • 23
  • 5
  • Do not use CryptoSwift if you care about either performance or security. CryptoSwift is 500 to 1000 times slower than Common Crypto and not well vetted or certified. – zaph Dec 08 '15 at 01:36
  • Why are you using CFB mode, the general case is to use CBC mode. – zaph Dec 08 '15 at 01:38
  • Just test code, don't mind :) – Neko Dec 08 '15 at 01:48

2 Answers2

1

To answer that question.

Your NodeJS code encrypt [0x5, 0x77, 0x5, 0x0, 0x3, 0x89, 0x20], but your CryptoSwift code encrypt [0x5, 0x77] then [0x5, 0x0, 0x3, 0x89, 0x20]. This is why you get different results.

Marcin
  • 3,694
  • 5
  • 32
  • 52
  • @Neko Wow, I did not look at the code well. You can't just concatenate encrypted bytes from separate encryptions. Perhaps full blocks in ECB but even that is broken thinking. Marcin: +1 – zaph Dec 12 '15 at 23:44
0

Unless the data is a multiple of the block size (16-bytes) and the data size is known by both sides a-priori to meet the requirement padding is required. The generally used padding is PKCS#7 (PKCS#5 is essentially the same).

In the code no padding is specified so the balance of the block will be whatever junk is in the buffer or perhaps the algorithm may null pad it, it is always best not to rely on non-standard defaults.

See the SO Answer for an example of using Common Crypto.

But the best thing to do is use RNCryptor for your encryption, it is available for several languages and platforms. It also handles all the bits that make encryption secure. It is well vetted and being actively developed.

Community
  • 1
  • 1
zaph
  • 111,848
  • 21
  • 189
  • 228
  • Thank you, I'm going to try to fix it. :) – Neko Dec 08 '15 at 01:51
  • Here is new question: https://github.com/krzyzanowskim/CryptoSwift/issues/175, could you please tell me why data not same? – Neko Dec 09 '15 at 07:30
  • I'm using RNCryptor, and seem to be getting terribly slow decryption speeds, such as 5-10 seconds to decrypt like 400 simple strings. – Brad Caldwell Jan 20 '18 at 01:29
  • Swift or node.js? Swift used common crypto so would use hardware acceleration, nothing should be faster. But if you are using a password as opposed to a key you will be deriving a key for each encryption and that process takes about 100ms by design. If you do not need key derivation and/or authentication use Common Crypto directly. There are several Swift implementations available on SO. – zaph Jan 20 '18 at 19:37