OpenSSL ile AES şifresi çözülemiyor


3

Ben bir ctf oyun üzerinde çalışıyorum:

ECB modunda AES ile şifrelenmiş. Tüm değerler base64 kodlanmış

ciphertext = 8LBUVZfDfI6wnggG1uUYuQsRoGd08pGwHCN++R5rabMW9PJmWHWcSrjy5Tfffj6L
key = 3q1FxGhuZ5fQYbjzDxgQ35==

Terminalimde şifrelemeyi şifreyle çözmeye çalıştım. -base64 bayrak, şanssız. O zaman ben gittim http://extranet.cryptomathic.com/aescalc , nerede, değerleri hex'e dönüştürdükten sonra şifresini çözebildim:

key: DEAD45C4686E6797D061B8F30F1810DF 
text: F0B0545597C37C8EB09E0806D6E518B90B11A06774F291B01C237EF91E6B69B316F4F26658759C4AB8F2E537DF7E3E8B
out: 7B796F755F73686F756C645F6E6F745F706F73745F7468655F61637475616C5F6374665F76616C75657D5F5F5F5F5F5F

Sonra terminalime dönerek denedim:

echo -n F0B0545597C37C8EB09E0806D6E518B90B11A06774F291B01C237EF91E6B69B316F4F26658759C4AB8F2E537DF7E3E8B | openssl enc -d -K DEAD45C4686E6797D061B8F30F1810DF -aes-128-ecb -nosalt

ama aynı hatayı aldım:

bad decrypt
140735124906848:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:evp_enc.c:531:

Bunu Ubuntu 17.04'te ve şimdi MacOSX'imde OpenSSL 1.0.2l kullanarak denedim. Neden kendi terminalimde şifresini çözemiyorum?


Bu bir CTF için olduğundan, gerçek değerleri çalışma yer tutucularıyla değiştirdim. ;)
Lery

Yanıtlar:


5

Çünkü openssl varsayılan olarak PKCS # 7 dolgusunu kullanır ve düz metininiz PKCS # 7 dolgusu içermez. Düz metniniz dolgulu ise, bayt değerine sahip dolgulu 5F. Seçeneğini kullanın -nopad bunun yerine, değerle doldurma 5F benim için bilinen herhangi bir dolgu şeması değil; kaldırılması gerekiyorsa, kendiniz çıkarmanız gerekir.

Şu anda girişi onaltılık aralıklarla gösteriyorsunuz. Onaltılık, bayt değerlerini değil, baytların gösterimidir. Kaynak malzemeyi doğrudan kullanarak bir dosyadan girmeniz gerekir. < Dosyanız için veya girişin kodunu çözerek hex.

Çıktı da ikili olacaktır; okunabilir herhangi bir düz metni temsil etmeyecektir. Bu nedenle sorunuzu değerlerle karşılaştırmadan önce çıktıyı onaltılık sayılara dönüştürmeniz gerekebilir.


1
Googled ve kendi cevaplarımdan birini aldım :)
Maarten Bodewes

1
5F şifresi çözülmüş mesajda görünür.
robert

1
Evet, doldurma işlemi blok şifresi / çalışma modu ile şifrelemeden önce ve bu nedenle şifre çözme işleminden sonra gerçekleştirilir.
Maarten Bodewes

1
Tamam şimdi anladım. kullanma -nopad başka hata mesajı yok, fakat çıktı yanlış, biraz çöp.
robert

1
AES 128 bit / 16 baytlık bir blok şifredir ve bu nedenle PKCS # 5 uyumlu dolgu kullanılamaz, çünkü yalnızca 64 bit / 8 bayt blok şifreler için tanımlanmıştır. . Çıktı çöp gibi görünüyorsa, büyük olasılıkla çıktının US-ASCII / UTF-8 (veya sisteminizde ayarlanmış herhangi bir karakter) olduğu yorumudur. Çıkışı kullanarak dosyaya yönlendirin > ve sonra bir hex editöründe açın, sonra sonuçları karşılaştır, daha önce değil.
Maarten Bodewes

3

Böyle şeyler yapmak için python veya başka bir scripting / programlama dili kullanmayı düşünebilirsiniz.

Programlı olarak yapmanın avantajları:

  • Ne zaman benzer bir şey yinelemeniz gerektiğinde, kodunuzu hazır olacak.
  • Neler olup bittiğini açıklamak için yorumlar yazabilirsiniz, bu yüzden bir kez daha önce ne yaptığınızı anlamanız gerekirse, umarım kod artı yorumlar size bunu sağlayacaktır.
  • Kodlama, bayt kullanımı vb. Birçok şey konsoldan daha kolaydır.
  • Çoğu dil çapraz platformdur, bu nedenle bir kez cihazınızı değiştirirseniz kolayca Windows, Linux, Android üzerinde çalışır.

Eldeki probleminizle ilgili olarak, her şeyi yapmak için python kullanılarak çözülebilir:

# we import the function we need from common librairies
from base64 import b64decode
from Crypto.Cipher import AES
from binascii import hexlify, unhexlify


# First we decode the message and the key from base64 into bytes:
msg = b64decode("8LBUVZfDfI6wnggG1uUYuQsRoGd08pGwHCN++R5rabMW9PJmWHWcSrjy5Tfffj6L")
key = b64decode("3q1FxGhuZ5fQYbjzDxgQ35==")

# We then instantiate a cipher_suite using AES with the provided key, in ECB mode
cipher_suite = AES.new(key, AES.MODE_ECB)

# We can decrypt the message using our cipher_suite:
recovered = cipher_suite.decrypt(msg)

# We can print it:
print ("plaintext: ", recovered)

# There is some garbage at the end, but if we display it in hexadecimal form:
print ("in hex:", hexlify(recovered))
# We can see it's just padding using '5f', so let's create a function to remove such padding:
def unpad(padded):
  # we declare the value of our padding:
  paddingByte = unhexlify('5f')
  # we do a loop, while the last byte is padding
  while padded[-1:]==paddingByte:
    # we remove the last byte
    padded = padded[:-1]
  # once it's done, we return
  return padded

# We can now use our function to remove padding:
print ("unpadded: ", unpad(recovered))

Şimdi, Python veya başka bir dil öğrenmek istemiyorsanız ve / veya Gerçekten mi hepsini terminalinizde yapmak istiyorsanız, bu da mümkündür: sonra doğrudan kullanarak her şeyi yapabilirsin borular Verileri bir komuttan diğerine geçirmek için, komut değiştirme openssl ve komutları için doğru anahtarı beslemek için base64 base64 plus'ı kullanmak için xxd İkili verileri hex'e çevirmek (openssl içindeki anahtar için) ve en sonunda kullan sed kaldırmak için 5f dolgu malzemesi:

echo "8LBUVZfDfI6wnggG1uUYuQsRoGd08pGwHCN++R5rabMW9PJmWHWcSrjy5Tfffj6L" | base64 --decode | openssl enc -d -K $(echo "3q1FxGhuZ5fQYbjzDxgQ35==" | base64 --decode | xxd  -c 16 -ps) -aes-128-ecb -nosalt -nopad | sed 's/_*$//g'

Nedenini bilmiyorum, ama şahsen python yaklaşımını daha temiz buluyorum.


Ayrıca, Maarten Bodewes'in size bildirdiği şekilde çöp aldığınızı da belirtmiştiniz, bu onaltılı değerleri OpenSSL'ye verdiğiniz gerçeğinden geliyor. doğrudan ikili veri (onaltılık değil) mesaj için, onaltılık bir anahtar sağlamanız gerekirken:

echo -n f0b0545597c37c8eb09e0806d6e518b90b11a06774f291b01c237ef91e6b69b316f4f26658759c4ab8f2e537df7e3e8b | xxd -r -p | openssl ...

Not: Muhtemelen CTF'lerde karşılaştığınız gerçek değerleri yayınlamaktan kaçınmalısınız, çünkü ilk refleksi değerleri google alan kişi için oyunu mahvedebilir.


2

base64 tarafından kod çözme

echo 8LBUVZfDfI6wnggG1uUYuQsRoGd08pGwHCN++R5rabMW9PJmWHWcSrjy5Tfffj6L | base64 -D > aesdata.dat

( -D Bir mac OS quirk olduğunu. Linux kullanma eğilimindedir -d veya --decode yerine).

Benzer şekilde:

echo 3q1FxGhuZ5fQYbjzDxgQ35== | base64 -D > aeskey.dat

ancak openssl, onaltılık değerleri parametrelerde bekler (ancak şifre dosyalarında ikili):

xxd -p < aeskey.dat verir dead45c4686e6797d061b8f30f1810df. Ya da karışıklıktan kaçınmak istiyorsanız önceki komuttan yararlanın.

En sonunda:

openssl enc -d -nopad -aes-128-ecb -K dead45c4686e6797d061b8f30f1810df -in aesdata.dat -out plain

şifresini çözecek. -Nopad, standart dışı dolgu kullanıldığı için şifre çözme hatasını önler.

şimdi hd plain sonucu kontrol etmek, ki bu aslında aradığın şeydi.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.