summaryrefslogtreecommitdiff
path: root/app.py
diff options
context:
space:
mode:
authorcyfraeviolae <cyfraeviolae>2022-08-25 02:16:03 -0400
committercyfraeviolae <cyfraeviolae>2022-08-26 04:18:14 -0400
commit96a52a1030c1bb27619372c6cebb633e02017847 (patch)
tree25dfcd7eb8a3c7a0ba71bd3edb8516f7fc401287 /app.py
parent62d6a6167e4121a536b813c883ac73773fef3ad7 (diff)
data
truncation truncation launch remove files
Diffstat (limited to 'app.py')
-rw-r--r--app.py43
1 files changed, 38 insertions, 5 deletions
diff --git a/app.py b/app.py
index d573efc..efc45bf 100644
--- a/app.py
+++ b/app.py
@@ -1,11 +1,12 @@
-import binascii
+import binascii, secrets
from flask import Flask, render_template, request, redirect, url_for
from flask_wtf import FlaskForm
from wtforms import StringField
from wtforms.validators import DataRequired, Length, ValidationError
+from Crypto.Cipher import AES
-from aesgcmanalysis import xor, gmac, gcm_encrypt, nonce_reuse_recover_secrets, gf128_to_bytes
+from aesgcmanalysis import xor, gmac, gcm_encrypt, nonce_reuse_recover_secrets, gf128_to_bytes, nonce_truncation_recover_secrets
app = Flask(__name__)
@@ -21,7 +22,6 @@ def hex_check(form, field):
def not_equal_to(other):
def helper(form, field):
- print(other, form['m1'], field)
if other not in form:
return
if form[other].data == field.data:
@@ -46,10 +46,10 @@ def nonce_reuse():
if form.validate():
skey = binascii.unhexlify(key)
snonce = binascii.unhexlify(nonce)
- c_forged, macs = solve(skey, snonce, bytes(m1, 'utf-8'), bytes(m2, 'utf-8'), bytes(mf, 'utf-8'))
+ c_forged, macs = solve_nonce_reuse(skey, snonce, bytes(m1, 'utf-8'), bytes(m2, 'utf-8'), bytes(mf, 'utf-8'))
return render_template('nonce-reuse.html', form=form, key=key, nonce=nonce, m1=m1, m2=m2, mf=mf, c_forged=c_forged, macs=macs)
-def solve(k, nonce, m1, m2, mf):
+def solve_nonce_reuse(k, nonce, m1, m2, mf):
aad1 = aad2 = b""
c1, mac1 = gcm_encrypt(k, nonce, aad1, m1)
c2, mac2 = gcm_encrypt(k, nonce, aad2, m2)
@@ -63,3 +63,36 @@ def solve(k, nonce, m1, m2, mf):
macs.append((gf128_to_bytes(h), s, mac))
return c_forged, macs
+class NonceTruncationForm(FlaskForm):
+ key = StringField('key', validators=[DataRequired(), Length(min=32, max=32), hex_check])
+ nonce = StringField('nonce', validators=[DataRequired(), Length(min=24, max=24), hex_check])
+ mf = StringField('forged message', validators=[DataRequired(), Length(min=1, max=64)])
+
+@app.route('/nonce-truncation', methods=['GET', 'POST'])
+def nonce_truncation():
+ form = NonceTruncationForm(meta={'csrf': False})
+ key = nonce = None
+ mf = ''
+ h = c_forged = mac = None
+ if form.is_submitted():
+ key, nonce, mf = form.key.data, form.nonce.data, form.mf.data
+ if form.validate():
+ skey = binascii.unhexlify(key)
+ snonce = binascii.unhexlify(nonce)
+ h, c_forged, mac = solve_nonce_truncation(skey, snonce, bytes(mf, 'utf-8'))
+ return render_template('nonce-truncation.html', form=form, key=key, nonce=nonce,
+ mf=mf, h=h, c_forged=c_forged, mac=mac)
+
+def solve_nonce_truncation(k, nonce, mf):
+ aad = b""
+ m = secrets.token_bytes(512)
+ c, mac = gcm_encrypt(k, nonce, aad, m, mac_bytes=1)
+
+ def oracle(base, aad, mac, nonce):
+ cipher = AES.new(k, mode=AES.MODE_GCM, nonce=nonce, mac_len=1)
+ cipher.update(aad)
+ cipher.decrypt_and_verify(base, mac)
+ h, s = nonce_truncation_recover_secrets(c, mac, nonce, 1, aad, oracle)
+ c_forged, aad_forged = xor(c, xor(m, mf)), b""
+ mac = gmac(h, s, aad_forged, c_forged)
+ return gf128_to_bytes(h), c_forged, mac[:1]