diff --git a/README.md b/README.md index 7090042..efa17d1 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Декодер PFX по ГОСТ 2012 от КриптоПро (aka CPfx) +# Декодер PFX по ГОСТ 2012 от КриптоПро ### Зависимости @@ -7,10 +7,6 @@ - - - - diff --git a/cpfx.py b/cpfx.py index e4140a6..219826d 100644 --- a/cpfx.py +++ b/cpfx.py @@ -1,10 +1,8 @@ -from pygost.asn1schemas.pfx import PFX, SafeContents, OctetStringSafeContents -from pygost.asn1schemas.prvkey import PrivateKeyAlgorithmIdentifier, PrivateKeyInfo -from pygost.asn1schemas.x509 import GostR34102012PublicKeyParameters +from pygost.asn1schemas.pfx import PFX, OctetStringSafeContents from pygost.gost341194 import GOST341194 from pygost.gost28147 import cfb_decrypt, ecb_decrypt, DEFAULT_SBOX -import sys, pyderasn, asn1, getpass, uuid -from pyderasn import ObjectIdentifier, OctetString, Integer +import sys, pyderasn, getpass, uuid +from pyderasn import ObjectIdentifier, OctetString, Integer, TagMismatch from schemas import * from pygost.kdf import kdf_gostr3411_2012_256 from base64 import standard_b64encode @@ -21,23 +19,6 @@ def printProgressBar (iteration, total, prefix = '', suffix = '', decimals = 1, if iteration == total: print() -def getOids(hexstr): - decoder = asn1.Decoder() - decoder.start(hexstr) - tag, value = decoder.read() - decoder.start(value) - tag, value = decoder.read() - tag, value = decoder.read() - decoder.start(value) - tag, value = decoder.read() - tag, value = decoder.read() - decoder.start(value) - tag, value = decoder.read() - params = value - tag, value = decoder.read() - dgst = value - return (params, dgst) - def key2pem(key, oids, algo): key = OctetString(key) algo = ObjectIdentifier(algo) @@ -88,7 +69,11 @@ def unwrap_gost(kek, data, sbox=DEFAULT_SBOX): print(" KEY = " + KEY.hex()) print(" IV = " + salt.hex()[:16]) result = cfb_decrypt(KEY, keybag, iv=bytes.fromhex(salt.hex()[:16])) -result = CPBlob().decode(result)[0] +try: + result = CPBlob().decode(result)[0] +except TagMismatch as e: + print("Расшифровка не удалась, скорее всего вы ввели неправильный пароль.\nЕсли вы считаете, что это всё таки ошибка создайте issue на Github") + quit() result = bytes(result["value"]).hex() algtype = result[:32][8:12] if algtype == "42aa": @@ -99,14 +84,19 @@ def unwrap_gost(kek, data, sbox=DEFAULT_SBOX): ukm = bytes(result["value"]["ukm"]).hex() cek_enc = bytes(result["value"]["cek"]["enc"]).hex() cek_mac = bytes(result["value"]["cek"]["mac"]).hex() -oids = getOids(bytes(result["value"]["oids"])) +oids = ( + result["value"]["oids"]["privateKeyAlgorithm"]["params"]["curve"], + result["value"]["oids"]["privateKeyAlgorithm"]["params"]["digest"], +) KEKe = kdf_gostr3411_2012_256(KEY, bytes.fromhex("26bdb878"), bytes.fromhex(ukm)) print(" KEKe = " + KEKe.hex()) if algtype == "46aa": #256 + print(" ALGO = ГОСТ Р 34.10-2012 (256 бит)") Ks = unwrap_gost(KEKe, bytes.fromhex(ukm + cek_enc + cek_mac)) elif algtype == "42aa": #512 + print(" ALGO = ГОСТ Р 34.10-2012 (512 бит)") cek_enc2 = [cek_enc[i:i+64] for i in range(0,len(cek_enc),64)] buff = [] for i in cek_enc2: diff --git a/schemas.py b/schemas.py index 5a7266b..df61aab 100644 --- a/schemas.py +++ b/schemas.py @@ -1,4 +1,4 @@ -from pyderasn import Sequence, OctetString, ObjectIdentifier, Any, Integer +from pyderasn import Sequence, OctetString, ObjectIdentifier, Any, Integer, BitString, tag_ctxc class CPParamsValue(Sequence): schema = ( ("salt", OctetString()), @@ -31,11 +31,29 @@ class CPExportBlobCek(Sequence): ("mac", OctetString()) ) +class PrivateKeyParameters(Sequence): + schema = ( + ("curve", ObjectIdentifier()), + ("digest", ObjectIdentifier()), + ) + +class PrivateKeyAlgorithm(Sequence): + schema = ( + ("algorithm", ObjectIdentifier()), + ("params", PrivateKeyParameters()) + ) + +class PrivateKeyInfo(Sequence): + schema = ( + ("version", BitString()), + ("privateKeyAlgorithm", PrivateKeyAlgorithm(impl=tag_ctxc(0))) + ) + class CPExportBlob2(Sequence): schema = ( ("ukm", OctetString()), ("cek", CPExportBlobCek()), - ("oids", Any()) + ("oids", PrivateKeyInfo(impl=tag_ctxc(0))) ) class CPExportBlob(Sequence): @@ -61,4 +79,4 @@ class PKey(Sequence): ("version", Integer(0)), ("params", PKeyPub()), ("key", OctetString()) - ) + ) \ No newline at end of file
Версия
asn12.6.0
PyDERASN 9.3