def _serialize_dsa_key(self, public_key, private_key): pub_seq = asn1.DerSequence() pub_seq[:] = [ 0, public_key.p, public_key.q, public_key.g, public_key.y ] public_key = pub_seq.encode() prv_seq = asn1.DerSequence() prv_seq[:] = [ 0, private_key.p, private_key.q, private_key.g, private_key.y, private_key.x ] private_key = prv_seq.encode() return public_key, private_key
def extract_emotet_rsakey(filedata): pub_matches = re.findall('''\x30[\x00-\xff]{100}\x02\x03\x01\x00\x01\x00\x00''', filedata) if pub_matches: pub_key = pub_matches[0][0:106] seq = asn1.DerSequence() seq.decode(pub_key) return RSA.construct((seq[0], seq[1]))
def testImportKey12(self): """Verify import of RSAPublicKey DER SEQUENCE, encoded with PEM""" der = asn1.DerSequence([17, 3]).encode() pem = der2pem(der) key = RSA.importKey(pem) self.assertEqual(key.n, 17) self.assertEqual(key.e, 3)
def extract_emotet_rsakey(pe): for section in pe.sections: if section.Name.replace(b'\x00',b'') == b'.data': data_section = section.get_data() pub_matches = re.findall(b"""\x00{4,12}(?=([\x01-\xff][\x00-\xff]{120}))""", data_section) if pub_matches: res_list = [] for match in pub_matches: xor_key = int.from_bytes(match[:4], byteorder='little') encoded_size = int.from_bytes(match[4:8], byteorder='little') decoded_size = ((xor_key ^ encoded_size)&0xfffffffc)+4 if decoded_size == 0x6c: offset = 8 res = b'' for count in range(int(0x6c/4)): off_from = offset+count*4 off_to = off_from+4 encoded_dw = int.from_bytes(match[off_from:off_to], byteorder='little') decoded = xor_key ^ encoded_dw res = res + decoded.to_bytes(4, byteorder='little') res_list.append(res) res_list = list(set(res_list)) pub_key = res_list[0][0:106] seq = asn1.DerSequence() seq.decode(pub_key) return RSA.construct((seq[0], seq[1]))
def genKeys(bits): key = DSA.generate(1024) seq = asn1.DerSequence() seq[:] = [0, key.p, key.q, key.g, key.y, key.x] k2 = "-----BEGIN DSA PRIVATE KEY-----\n%s-----END DSA PRIVATE KEY-----" % seq.encode( ).encode("base64") return k2
def test_certificate_matches_private_key(self): """ A certificate matches the private key it is meant to be paired with. """ priv = self.credential.credential.keypair.keypair.original pub = self.credential.credential.certificate pub = pub.getPublicKey().original pub_asn1 = crypto.dump_privatekey(crypto.FILETYPE_ASN1, pub) priv_asn1 = crypto.dump_privatekey(crypto.FILETYPE_ASN1, priv) pub_der = asn1.DerSequence() pub_der.decode(pub_asn1) priv_der = asn1.DerSequence() priv_der.decode(priv_asn1) pub_modulus = pub_der[1] priv_modulus = priv_der[1] self.assertEqual(pub_modulus, priv_modulus)
def export_dsa_key_to_file(file_name, key, encoding='base64'): from Crypto.Util import asn1 with open(file_name) as f: seq = asn1.DerSequence() seq[:] = [0, key.p, key.q, key.g, key.y, key.x] template = '-----BEGIN DSA PRIVATE KEY-----\n%s-----END DSA PRIVATE KEY-----' exported_key = template % seq.encode().encode(encoding) f.write(exported_key)
def verify_sig(self, encoded_cert): der = asn1.DerSequence() der.decode(encoded_cert) der_sig = asn1.DerObject() der_sig.decode(der[2]) sig = der_sig.payload self.assertEqual(b'\x00', sig[:1]) crypto.verify(self.ca.cert, sig[1:], der[0], 'sha256')
def sig_bytes_to_asn1(sig): part_len = int(len(sig) / 2) r = int.from_bytes(sig[:part_len], 'big') s = int.from_bytes(sig[part_len:], 'big') der = asn1.DerSequence() der.append(r) der.append(s) return der.encode()
def import_dsa_private_key(str): from Crypto.Util import asn1 from Crypto.PublicKey import DSA seq2 = asn1.DerSequence() data = "\n".join(str.strip().split("\n")[1:-1]).decode("base64") seq2.decode(data) p, q, g, y, x = seq2[1:] key2 = DSA.construct((y, g, p, q, x)) return key2
def load_dsa_key(pub_key): der = base64.b64decode(pub_key) cert = asn1.DerSequence() cert.decode(der) y_asn = asn1.DerInteger() y_asn.decode(cert[1][4:]) y = y_asn.value pubkeyInfo = asn1.DerSequence() pubkeyInfo.decode(cert[0]) pubkeys = asn1.DerSequence() pubkeys.decode(pubkeyInfo[1]) p, q, g = pubkeys[:] return DSA.construct((y, g, p, q))
def asn1_to_sig_bytes(asn, tolen): der = asn1.DerSequence() der.decode(asn) sig = bytes() part_len = int(tolen / 2) # Wrap with int() for Py2 sig += int(der[0]).to_bytes(part_len, 'big') sig += int(der[1]).to_bytes(part_len, 'big') return sig
def _serialize_dsa_key(self, public_key, private_key): pub_seq = asn1.DerSequence() pub_seq[:] = [ 0, public_key.p, public_key.q, public_key.g, public_key.y ] public_key = "-----BEGIN DSA PUBLIC KEY-----\n%s"\ "-----END DSA PUBLIC KEY-----" % pub_seq.encode().encode("base64") prv_seq = asn1.DerSequence() prv_seq[:] = [ 0, private_key.p, private_key.q, private_key.g, private_key.y, private_key.x ] private_key = "-----BEGIN DSA PRIVATE KEY-----\n%s"\ "-----END DSA PRIVATE KEY-----" % prv_seq.encode().encode("base64") return (public_key, private_key)
def import_dsa_key_from_file(file_name, encoding='base64'): from Crypto.Util import asn1 with open(file_name) as f: seq = asn1.DerSequence() data = '\n'.join(f.read().strip().split('\n')[1:-1].decode(encoding)) seq.decode(data) p, q, g, y, x = seq[1:] key = DSA.construct((y, g, p, q, x)) return key
def decode_seq_set(data): result = [] offset = 0 while offset < len(data): der = asn1.DerSequence() length = der.decode(data[offset:]) offset += length result.append(list(der)) return result
def test_certificate_matches_private_key(self): """ A certificate matches the private key it is meant to be paired with. """ path = FilePath(self.mktemp()) path.makedirs() ca = RootCredential.initialize(path, b"mycluster") priv = ca.credential.keypair.keypair.original pub = ca.credential.certificate.getPublicKey().original pub_asn1 = crypto.dump_privatekey(crypto.FILETYPE_ASN1, pub) priv_asn1 = crypto.dump_privatekey(crypto.FILETYPE_ASN1, priv) pub_der = asn1.DerSequence() pub_der.decode(pub_asn1) priv_der = asn1.DerSequence() priv_der.decode(priv_asn1) pub_modulus = pub_der[1] priv_modulus = priv_der[1] self.assertEqual(pub_modulus, priv_modulus)
def import_public_key(self, filename): with open(filename, "rb") as f: b64enc_key = f.read() b64dec_key = base64.b64decode(b64enc_key) seq = asn1.DerSequence() seq.decode(b64dec_key) pubkey = RSA.construct((seq[0], seq[1])) pubkey = PKCS1_OAEP.new(pubkey) self.RSA_PUBLIC_KEY = pubkey
def crl_dates(crl_der): crl_seq = asn1.DerSequence() crl_seq.decode(crl_der) if len(crl_seq) != 3: raise ValueError("unknown crl format") tbsCertList = asn1.DerSequence() tbsCertList.decode(crl_seq[0]) thisUpdate = asn1.DerObject() nextUpdate = asn1.DerObject() if isinstance(tbsCertList[0], types.StringTypes): # CRL v1 thisUpdate.decode(tbsCertList[2]) nextUpdate.decode(tbsCertList[3]) else: if tbsCertList[0] > 1: raise ValueError("unsupported CRL profile version: %d" % tbsCertList[0]) thisUpdate.decode(tbsCertList[3]) nextUpdate.decode(tbsCertList[4]) if thisUpdate.typeTag not in time_formats or \ nextUpdate.typeTag not in time_formats: raise ValueError("invalid CRL date/time fields") return time_formats[nextUpdate.typeTag](nextUpdate)
def extract_rsakey(self, data): pubkey = "" pemkey_match = re.findall('''\x30[\x00-\xFF]{100}\x02\x03\x01\x00\x01\x00\x00''',data) if pemkey_match: pemkey = pemkey_match[0][0:106] seq = asn1.DerSequence() seq.decode(pemkey) pemkey = RSA.construct((seq[0],seq[1])) pubkey = pemkey.exportKey() return pubkey
def verify_key_cert_pair(self, cert_str, key_str): c = OpenSSL.crypto cert = None key = None try: cert = c.load_certificate(c.FILETYPE_PEM, cert_str) key = c.load_privatekey(c.FILETYPE_PEM, key_str) except: pass if not cert or not key: return None pub = cert.get_pubkey() # Only works for RSA (I think) if pub.type() != c.TYPE_RSA or key.type() != c.TYPE_RSA: raise Exception('Can only handle RSA keys') # This seems to work with public as well pub_asn1 = c.dump_privatekey(c.FILETYPE_ASN1, pub) priv_asn1 = c.dump_privatekey(c.FILETYPE_ASN1, key) # Decode DER pub_der = asn1.DerSequence() pub_der.decode(pub_asn1) priv_der = asn1.DerSequence() priv_der.decode(priv_asn1) # Get the modulus pub_modulus = pub_der[1] priv_modulus = priv_der[1] if pub_modulus == priv_modulus: sub = cert.get_subject() return str(sub.commonName) else: return None
def check_signature(blob, x509_certificate_pem, signature): """Verifies signature produced by 'sign_blob' function. Args: blob: binary buffer to check the signature for. x509_certificate_pem: PEM encoded x509 certificate, may be obtained with get_service_public_certificates() and get_x509_certificate_by_name(). signature: the signature, as returned by sign_blob function. Returns: True if signature is correct. """ # See http://stackoverflow.com/a/12921889. # Lazy import Crypto, since not all service that use 'components' may need it. from Crypto.Hash import SHA256 from Crypto.PublicKey import RSA from Crypto.Signature import PKCS1_v1_5 from Crypto.Util import asn1 # Convert PEM to DER. There's a function for this in 'ssl' module # (ssl.PEM_cert_to_DER_cert), but 'ssl' is not importable in GAE sandbox # on dev server (C extension is not whitelisted). lines = x509_certificate_pem.strip().split('\n') if (len(lines) < 3 or lines[0] != '-----BEGIN CERTIFICATE-----' or lines[-1] != '-----END CERTIFICATE-----'): raise CertificateError('Invalid certificate format') der = base64.b64decode(''.join(lines[1:-1])) # Extract subjectPublicKeyInfo field from X.509 certificate (see RFC3280). cert = asn1.DerSequence() cert.decode(der) tbsCertificate = asn1.DerSequence() tbsCertificate.decode(cert[0]) subjectPublicKeyInfo = tbsCertificate[6] verifier = PKCS1_v1_5.new(RSA.importKey(subjectPublicKeyInfo)) digest = hashlib.sha512(blob).digest() return verifier.verify(SHA256.new(digest), signature)
def generate_key(modulus_b64, exp_b64): """ Generates an RSA public key given a base64-encoded modulus and exponent :param modulus_b64: base64-encoded modulus :param exp_b64: base64-encoded exponent :return: an RSA public key """ mod = int(b64decode(modulus_b64).encode('hex'), 16) exp = int(b64decode(exp_b64).encode('hex'), 16) seq = asn1.DerSequence() seq.append(mod) seq.append(exp) der = seq.encode() return RSA.importKey(der)
def _get_mod(self): """ Returns the modulus of the RSA key in bn form.""" buf = ctypes.create_string_buffer(1024) pBuf = ctypes.c_char_p(ctypes.addressof(buf)) n = _ssl.i2d_RSAPublicKey(self.key, ctypes.byref(pBuf)) s = buf.raw[:n] seq = asn1.DerSequence() seq.decode(s) # s[0] is n, s[1] is e # Convert to bn self.bn_n = _ssl.BN_new() seq_bytes = ctypes.c_char_p(seq[0].to_bytes(256, byteorder='big')) return _ssl.BN_bin2bn(seq_bytes, self.size, self.bn_n)
def gen_dsa_pub_key(dsa_key, old_key): der = base64.b64decode(old_key) cert = asn1.DerSequence() cert.decode(der) y_asn = asn1.DerInteger() y_asn.decode(cert[1][4:]) y = y_asn.value pubkeyInfo = asn1.DerSequence() pubkeyInfo.decode(cert[0]) pubkeys = asn1.DerSequence() pubkeys[:] = [dsa_key.p, dsa_key.q, dsa_key.g] pubkeyInfo[1] = pubkeys.encode() y_asn = asn1.DerInteger(dsa_key.y).encode() y_asn_prefix = struct.pack('BBBB', 3, 0x81, len(y_asn) + 1, 0) cert[:] = [pubkeyInfo.encode(), y_asn_prefix + y_asn] return base64.b64encode(cert.encode())
def check_crypto(crt, key): """ Checks if the key matches the certificate. """ agent_crt = crypto.load_certificate(crypto.FILETYPE_PEM, crt) agent_key = crypto.load_privatekey(crypto.FILETYPE_PEM, key) agent_pub = agent_crt.get_pubkey() # This seems to work with public as well pub_asn1 = crypto.dump_privatekey(crypto.FILETYPE_ASN1, agent_pub) priv_asn1 = crypto.dump_privatekey(crypto.FILETYPE_ASN1, agent_key) # Decode DER pub_der = asn1.DerSequence() pub_der.decode(pub_asn1) priv_der = asn1.DerSequence() priv_der.decode(priv_asn1) # Get the modulus pub_modulus = pub_der[1] priv_modulus = priv_der[1] return pub_modulus == priv_modulus
def test_old_license(): demoBytes = base64.b64decode(demoLicense) content, sig_content = getLicenseContent(demoBytes) sig_der = asn1.DerSequence() sig_der.decode(sig_content) sig = (sig_der[0], sig_der[1]) key = load_dsa_key(demoKeys) h = SHA.new(content).digest() if key.verify(h, sig): print("OK") else: print("Incorrect signature")
def extract_cert_signature(self, cert): # TODO: Can this be done from M2Crypto's certificate object? der_cert = cert.as_der() der = asn1.DerSequence() der.decode(der_cert) der_sig_raw = der[2] der_sig_dec = asn1.DerObject() der_sig_dec.decode(der_sig_raw) sig0 = der_sig_dec.payload sig = sig0[1:] return sig
def getASN1Sequence(privateKey): """Get an ASN.1 DER sequence string representation of the key's public modulus and exponent. :type privateKey: ``Crypto.PublicKey.RSA`` :param privateKey: A private RSA key. :rtype: bytes :returns: The ASN.1 DER-encoded string representation of the public portions of the **privateKey**. """ seq = asn1.DerSequence() seq.append(privateKey.n) seq.append(privateKey.e) asn1seqString = seq.encode() return asn1seqString
def signMsg(text, imported_key): seq2 = asn1.DerSequence() data = '\n'.join(imported_key.strip().split('\n')[1:-1]).decode('base64') seq2.decode(data) p, q, g, y, x = seq2[1:] key2 = DSA.construct((y, g, p, q, x)) k1 = random.StrongRandom().randint(1, key2.q - 1) h = SHA.new(text).digest() sig = key2.sign(h, k1) return sig
def create_privatekey_dsa_pem(self, dsakey_object): """ http://stackoverflow.com/questions/5938664/how-to-generate-the-pem-serialization-for-the-public-rsa-dsa-key """ dsa_p = self.mh.read_bignum(dsakey_object.p) dsa_q = self.mh.read_bignum(dsakey_object.q) dsa_g = self.mh.read_bignum(dsakey_object.g) dsa_y = self.mh.read_bignum(dsakey_object.y) dsa_x = self.mh.read_bignum(dsakey_object.x) rawkey = (dsa_y, dsa_g, dsa_p, dsa_q, dsa_x) dsakey = DSA.construct(rawkey) seq = asn1.DerSequence() seq[:] = [0, dsakey.p, dsakey.q, dsakey.g, dsakey.y, dsakey.x] exported_key = "-----BEGIN DSA PRIVATE KEY-----\n%s-----END DSA PRIVATE KEY-----" % seq.encode( ).encode("base64") return exported_key