aespipe 파일 연결: 첫 번째 파일 이후 512바이트마다 잘못된 바이트

aespipe 파일 연결: 첫 번째 파일 이후 512바이트마다 잘못된 바이트

스트림을 암호화하려고 합니다.에스펙로그 파일에 추가하면 실행할 때마다 동일한 파일에 추가하는 것이 합리적이므로 다음과 같은 작업을 수행하고 싶습니다.

my_stream | aespipe -K my_key >> aes_logfile

저는 512바이트 청크를 작성하는 것을 고려했으며 aespipe항상 이러한 크기의 증분으로 데이터를 출력하도록 스트림을 패딩했습니다. 나거의내 계획을 실행해 보자단, aespipe는 첫 번째 파일 이후 512바이트 증가마다 첫 번째 바이트를 손상시킵니다.. 예를 들어 다음 파일 that_file(줄로 끝남 ~)은 512바이트입니다.

Hey StackOverflow, here is a  ~
small example. The lines are  ~
32 characters long (including ~
the trailing \n) and with     ~
aespipe you can encrypt this  ~
file with                     ~
                              ~
cat this_file | aespipe -K \  ~
 your_key_with_one_line.gpg \ ~
 > enc_file                   ~
                              ~
then you can concatenate onto ~
the encrypted file again with ~
 >> and get a new file.       ~
Note that this file is 512 B. ~
So it is the right block size ~

이는 다음의 출력입니다.

# First go
cat that_file | aespipe -K my_key.gpg >  aes_logfile
# Second go
cat that_file | aespipe -K my_key.gpg >> aes_logfile

# Try decrypting
cat aes_logfile | aespipe -d -K my_key.gpg

주석이 달린 출력:

Hey StackOverflow, here is a  ~
small example. The lines are  ~
32 characters long (including ~
the trailing \n) and with     ~
aespipe you can encrypt this  ~
file with                     ~
                              ~
cat this_file | aespipe -K \  ~
 your_key_with_one_line \     ~
 > enc_file                   ~
                              ~
then you can concatenate onto ~
the encrypted file again with ~
 >> and get a new file.       ~
Note that this file is 512 B. ~
So it is the right block size ~
Iey StackOverflow, here is a  ~    # <-- H became I!
small example. The lines are  ~
32 characters long (including ~
the trailing \n) and with     ~
aespipe you can encrypt this  ~
file with                     ~
                              ~
cat this_file | aespipe -K \  ~
 your_key_with_one_line \     ~
 > enc_file                   ~
                              ~
then you can concatenate onto ~
the encrypted file again with ~
 >> and get a new file.       ~
Note that this file is 512 B. ~
So it is the right block size ~

512바이트마다 발생하는데 그 이유는 모르겠습니다. 이 문제를 해결할 방법이 있나요? ( aespipe version 2.4d)

답변1

음, 재현할 수 있어요.

# dd count=1 if=/dev/zero | aespipe > aes_zero
Password: Error: Password must be at least 20 characters.
# dd count=1 if=/dev/zero | aespipe >> aes_zero
Password: Error: Password must be at least 20 characters.
# cat aes_zero | aespipe -d | hexdump -C
Password: Error: Password must be at least 20 characters.
00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000200  01 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
          ^^
00000210  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000400

암호문:

# hexdump -C aes_zero
00000000  b3 a3 72 9b 18 5b 6b 73  e5 48 88 d1 8b 66 e3 10  |..r..[ks.H...f..|
00000010  a8 a0 ee d3 7e 08 91 86  6b f7 30 b2 ea 6a 58 0b  |....~...k.0..jX.|
[...]
000001e0  d9 2a 60 22 c9 4a 37 5c  47 21 65 0a bb f3 a8 7d  |.*`".J7\G!e....}|
000001f0  50 9f ef 38 9a c1 95 2b  ff 85 c7 16 cc 90 a7 18  |P..8...+........|
00000200  b3 a3 72 9b 18 5b 6b 73  e5 48 88 d1 8b 66 e3 10  |..r..[ks.H...f..|
00000210  a8 a0 ee d3 7e 08 91 86  6b f7 30 b2 ea 6a 58 0b  |....~...k.0..jX.|
[...]
000003e0  d9 2a 60 22 c9 4a 37 5c  47 21 65 0a bb f3 a8 7d  |.*`".J7\G!e....}|
000003f0  50 9f ef 38 9a c1 95 2b  ff 85 c7 16 cc 90 a7 18  |P..8...+........|
00000400

암호문이 반복되므로 전혀 발생해서는 안되는 암호화가 잘못된 것임을 이미 알 수 있습니다.

암호문 자체에는 아무런 문제가 없습니다.

# dd count=1 if=aes_zero | md5sum
1+0 records in
1+0 records out
512 bytes (512 B) copied, 0.00136312 s, 376 kB/s
f328ce6ff88545bc803b033561cbdffd  -
# dd count=1 skip=1 if=aes_zero | md5sum
1+0 records in
1+0 records out
512 bytes (512 B) copied, 0.00148213 s, 345 kB/s
f328ce6ff88545bc803b033561cbdffd  -

그래서 동일하며 복호화 중에 잘못된 바이트가 있습니다.

사실 제가 순진하게 예상한 것은 1바이트 편차가 아니라 처음 512바이트 이후의 임의의 데이터였습니다. 가장 일반적으로 사용되는 암호화 방식의 경우 암호문 중복을 피하기 위해 각 섹터의 IV가 달라야 하며 결과는 완전히 달라야 합니다.

한 번에 1024바이트를 암호화합니다.

# dd count=2 if=/dev/zero | aespipe >> aes_zero2
Password: Error: Password must be at least 20 characters.
# hexdump -C aes_zero2
00000000  b3 a3 72 9b 18 5b 6b 73  e5 48 88 d1 8b 66 e3 10  |..r..[ks.H...f..|
00000010  a8 a0 ee d3 7e 08 91 86  6b f7 30 b2 ea 6a 58 0b  |....~...k.0..jX.|
...
000001e0  d9 2a 60 22 c9 4a 37 5c  47 21 65 0a bb f3 a8 7d  |.*`".J7\G!e....}|
000001f0  50 9f ef 38 9a c1 95 2b  ff 85 c7 16 cc 90 a7 18  |P..8...+........|
00000200  60 89 3e 37 87 1c 37 31  1a 11 50 b6 99 50 d3 74  |`.>7..71..P..P.t|
00000210  af a9 a2 30 3d e6 72 5f  f3 96 6d 3b 9e 5b 33 6f  |...0=.r_..m;.[3o|
...
000003e0  3f d3 2e 9a 18 ad 7a c9  5a ee 04 99 28 e6 af 3f  |?.....z.Z...(..?|
000003f0  a3 a9 71 be 1a 56 35 01  06 b9 57 dd fc 42 7c 47  |..q..V5...W..B|G|

보시다시피, 암호문은 전혀 반복되지 않습니다. 따라서 연결에서 잘못된 암호문이 생성되고(IV가 올바르게 설정되지 않음) 어쨌든 그렇게 많은 전체 텍스트를 얻는 것은 큰 놀라움이며 좋은 암호화가 아닙니다. 암호문을 다른 오프셋으로 이동하여 합리적인 결과를 얻을 수 없어야 합니다(처음 몇 바이트만 잘못된 IV의 영향을 받습니다).


LUKS(aes-xts-plain64)를 사용하여 동일한 것을 재현하려고 합니다.

# truncate -s 1024 luks_zero
# losetup --find --show luks_zero
/dev/loop9
# cryptsetup open --type plain --cipher aes-xts-plain64 /dev/loop9 luks_zero
Enter passphrase for /dev/loop9: Error: Password must be at least 20 characters.
# dd if=/dev/zero of=/dev/mapper/luks_zero
dd: writing to '/dev/mapper/luks_zero': No space left on device
3+0 records in
2+0 records out
1024 bytes (1.0 kB, 1.0 KiB) copied, 0.000719156 s, 1.4 MB/s

LUKS로 암호화된 0입니다. 반복되는 암호문:

# sync
# dd count=1 seek=1 if=/dev/loop9 of=/dev/loop9
# hexdump -C /dev/loop9
00000000  1c 18 b1 e6 57 9c a1 60  8c 98 f0 d3 59 8b 97 0c  |....W..`....Y...|
00000010  bc fc 8a 62 68 52 51 f1  51 49 bf 21 2e f5 bc 84  |...bhRQ.QI.!....|
[...]
000001e0  4a e0 ef eb 8f 09 18 a8  73 95 0b 2c 59 01 69 1b  |J.......s..,Y.i.|
000001f0  92 71 e6 0d dd 3b 71 b5  22 f4 34 1c e1 4a 95 71  |.q...;q.".4..J.q|
00000200  1c 18 b1 e6 57 9c a1 60  8c 98 f0 d3 59 8b 97 0c  |....W..`....Y...|
00000210  bc fc 8a 62 68 52 51 f1  51 49 bf 21 2e f5 bc 84  |...bhRQ.QI.!....|
[...]
000003e0  4a e0 ef eb 8f 09 18 a8  73 95 0b 2c 59 01 69 1b  |J.......s..,Y.i.|
000003f0  92 71 e6 0d dd 3b 71 b5  22 f4 34 1c e1 4a 95 71  |.q...;q.".4..J.q|
00000400

암호문이 완벽하게 복사되었습니다. 해독 결과:

# hexdump -C /dev/mapper/luks_zero 
00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000200  b7 6c 5c 84 3d 7d dc 58  fc d5 ee 7f 20 c0 d5 09  |.l\.=}.X.... ...|
00000210  a8 78 f8 d8 38 4b 6a 24  bb b1 d2 65 b8 5c 2b ac  |.x..8Kj$...e.\+.|
[...]
000003e0  08 31 74 f4 59 92 3b 7f  0f fa b9 36 2e de 53 e2  |.1t.Y.;....6..S.|
000003f0  24 83 01 53 6e 56 dc a5  3a 3f 1b 4e d5 0a fd a9  |$..SnV..:?.N....|
00000400

512바이트의 0과 완전한 가비지가 뒤따릅니다. 이것은 암호화폐가 좋다는 것을 증명하지는 않지만 aespipe에서 얻는 것과 같이 명백히 나쁘지는 않습니다.


이제 이는 잘못된 IV로 인한 것이므로 먼저 올바른 IV로 암호화했는지 확인하면 됩니다. 다음과 같은 플래그가 aespipe있습니다 .-O sectornumber

   -O sectornumber
          Set IV offset in 512 byte units. Default is zero. Data is encrypted  in  512  byte  CBC
          chains  and  each  512  byte  chain  starts with IV whose computation depends on offset
          within the data. This option can be used to start encryption or decryption in middle of
          some existing encrypted disk image.

사물을 암호화하고 연결하는 새로운 방법:

# dd count=1 if=/dev/zero | aespipe -O 0 > aes_zero
Password: Error: Password must be at least 20 characters.
# dd count=1 if=/dev/zero | aespipe -O 1 >> aes_zero
Password: Error: Password must be at least 20 characters.

일회성 암호화와 일치하는지 확인하세요.

# md5sum aes_zero aes_zero2 
3b0479e04a46a3d268dc4252e066d2b5  aes_zero
3b0479e04a46a3d268dc4252e066d2b5  aes_zero2

이제 암호 해독 결과가 올바른지 확인합니다.

# cat aes_zero | aespipe -d | hexdump -C
Password: Error: Password must be at least 20 characters.
00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000400

DNA가 일치하고, 타이밍이 작동하고, 모든 것이 확인됩니다... 음, 암호화폐 자체를 개선하지는 않지만 당면한 문제를 해결하며 아마도 목적에 충분할 것입니다.

파일 크기에서 올바른 -O sectornumber값을 동적으로 파생시키는 것은 독자의 연습 문제로 남아 있습니다.

관련 정보