def testEncode4(self): # One very long integer der = DerSequence() der.append(2 ** 2048) self.assertEquals( der.encode(), b("0\x82\x01\x05") + b("\x02\x82\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00") + b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") + b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") + b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") + b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") + b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") + b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") + b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") + b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") + b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") + b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") + b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") + b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") + b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") + b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") + b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") + b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") + b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") + b("\x00\x00\x00\x00\x00\x00\x00\x00\x00"), )
def testEncode7(self): # One integer and another type (no matter what it is) der = DerSequence() der.append(0x180) der.append(b('\x00\x02\x00\x00')) self.assertEqual(der.encode(), b('0\x08\x02\x02\x01\x80\x00\x02\x00\x00')) self.assertFalse(der.hasOnlyInts())
def exportKey(self, format='PEM', public=False, type=None): """Export the RSA key. A string is returned with the encoded public or the private half under the selected format. format: 'DER' (PKCS#1) or 'PEM' (RFC1421) """ if type == 'ssh-rsa' and public: return ''.join(binascii.b2a_base64('\x00\x00\x00\x07ssh-rsa\x00\x00\x00\x03' + '\x00\x00\x01\x01\x00'.join([long_to_bytes(self.e), long_to_bytes(self.n)])).split("\n")) der = DerSequence() if not public and self.has_private(): keyType = "RSA PRIVATE" der[:] = [ 0, self.n, self.e, self.d, self.p, self.q, self.d % (self.p-1), self.d % (self.q-1), self.u ] else: keyType = "PUBLIC" der.append('\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01\x05\x00') bitmap = DerObject('BIT STRING') derPK = DerSequence() derPK[:] = [ self.n, self.e ] bitmap.payload = '\x00' + derPK.encode() der.append(bitmap.encode()) if format=='DER': return der.encode() if format=='PEM': pem = "-----BEGIN %s KEY-----\n" % keyType binaryKey = der.encode() # Each BASE64 line can take up to 64 characters (=48 bytes of data) chunks = [ binascii.b2a_base64(binaryKey[i:i+48]) for i in range(0, len(binaryKey), 48) ] pem += ''.join(chunks) pem += "-----END %s KEY-----" % keyType return pem return ValueError("")
def testEncode7(self): # One integer and another type (already encoded) der = DerSequence() der.append(0x180) der.append(b('0\x03\x02\x01\x05')) self.assertEqual(der.encode(), b('0\x09\x02\x02\x01\x800\x03\x02\x01\x05')) self.assertFalse(der.hasOnlyInts())
def testEncode8(self): # One integer and another type (yet to encode) der = DerSequence() der.append(0x180) der.append(DerSequence([5])) self.assertEquals(der.encode(), b('0\x09\x02\x02\x01\x800\x03\x02\x01\x05')) self.failIf(der.hasOnlyInts())
def testEncode8(self): # One integer and another type (yet to encode) der = DerSequence() der.append(0x180) der.append(DerSequence([5])) self.assertEqual(der.encode(), b('0\x09\x02\x02\x01\x800\x03\x02\x01\x05')) self.assertFalse(der.hasOnlyInts())
def testEncode6(self): # One integer and another type (no matter what it is) der = DerSequence() der.append(0x180L) der.append('\x00\x02\x00\x00') self.assertEquals(der.encode(), '0\x08\x02\x02\x01\x80\x00\x02\x00\x00') self.failIf(der.hasOnlyInts())
def testEncode6(self): # Two positive integers der = DerSequence() der.append(0x180) der.append(0xFF) self.assertEquals(der.encode(), b('0\x08\x02\x02\x01\x80\x02\x02\x00\xff')) self.failUnless(der.hasOnlyInts()) self.failUnless(der.hasOnlyInts(False)) # Two mixed integers der = DerSequence() der.append(2) der.append(-2) self.assertEquals(der.encode(), b('0\x06\x02\x01\x02\x02\x01\xFE')) self.assertEquals(der.hasInts(), 1) self.assertEquals(der.hasInts(False), 2) self.failIf(der.hasOnlyInts()) self.failUnless(der.hasOnlyInts(False)) # der.append(0x01) der[1:] = [9, 8] self.assertEquals(len(der), 3) self.assertEqual(der[1:], [9, 8]) self.assertEqual(der[1:-1], [9]) self.assertEquals(der.encode(), b('0\x09\x02\x01\x02\x02\x01\x09\x02\x01\x08'))
def testEncode4(self): # One very long integer der = DerSequence() der.append(2**2048) self.assertEquals( der.encode(), '0\x82\x01\x05' '\x02\x82\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00' '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' '\x00\x00\x00\x00\x00\x00\x00\x00\x00')
def exportKey(self, format='PEM'): """Export the RSA key. A string is returned with the encoded public or the private half under the selected format. format: 'DER' (PKCS#1) or 'PEM' (RFC1421) """ der = DerSequence() if self.has_private(): keyType = "RSA PRIVATE" der[:] = [ 0, self.n, self.e, self.d, self.p, self.q, self.d % (self.p-1), self.d % (self.q-1), self.u ] else: keyType = "PUBLIC" der.append(b('\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01\x05\x00')) bitmap = DerObject('BIT STRING') derPK = DerSequence() derPK[:] = [ self.n, self.e ] bitmap.payload = b('\x00') + derPK.encode() der.append(bitmap.encode()) if format=='DER': return der.encode() if format=='PEM': pem = b("-----BEGIN %s KEY-----\n" % keyType) binaryKey = der.encode() # Each BASE64 line can take up to 64 characters (=48 bytes of data) chunks = [ binascii.b2a_base64(binaryKey[i:i+48]) for i in range(0, len(binaryKey), 48) ] pem += b('').join(chunks) pem += b("-----END %s KEY-----" % keyType) return pem return ValueError("")
def _importKeyDER(self, externKey): der = DerSequence() der.decode(externKey, True) 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(inverse(der[4],der[5])) # Add p^{-1} mod q del der[0] # Remove version return self.construct(der[:]) if len(der)==2: # The DER object is a SEQUENCE with two elements: # a SubjectPublicKeyInfo SEQUENCE and an opaque BIT STRING. # # The first element is always the same: # 0x30 0x0D SEQUENCE, 12 bytes of payload # 0x06 0x09 OBJECT IDENTIFIER, 9 bytes of payload # 0x2A 0x86 0x48 0x86 0xF7 0x0D 0x01 0x01 0x01 # rsaEncryption (1 2 840 113549 1 1 1) (PKCS #1) # 0x05 0x00 NULL # # The second encapsulates the actual ASN.1 RSAPublicKey element. if der[0]==b('\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01\x05\x00'): bitmap = DerObject() bitmap.decode(der[1], True) if bitmap.typeTag==b('\x03')[0] and bitmap.payload[0]==b('\x00')[0]: der.decode(bitmap.payload[1:], True) if len(der)==2 and der.hasOnlyInts(): return self.construct(der[:]) raise ValueError("RSA key format is not supported")
def testEncode7(self): # One integer and another type (already encoded) der = DerSequence() der.append(0x180) der.append(b('0\x03\x02\x01\x05')) self.assertEqual(der.encode(), b('0\x09\x02\x02\x01\x800\x03\x02\x01\x05')) self.assertFalse(der.hasOnlyInts())
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")
def testEncode7(self): # One integer and another type (no matter what it is) der = DerSequence() der.append(0x180) der.append(b('\x00\x02\x00\x00')) self.assertEqual(der.encode(), b('0\x08\x02\x02\x01\x80\x00\x02\x00\x00')) self.assertFalse(der.hasOnlyInts())
def exportKey(self, format="PEM"): """Export the RSA key. A string is returned with the encoded public or the private half under the selected format. format: 'DER' (PKCS#1) or 'PEM' (RFC1421) """ der = DerSequence() if self.has_private(): keyType = "RSA PRIVATE" der[:] = [0, self.n, self.e, self.d, self.p, self.q, self.d % (self.p - 1), self.d % (self.q - 1), self.u] else: keyType = "PUBLIC" der.append("\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01\x05\x00") bitmap = DerObject("BIT STRING") derPK = DerSequence() derPK[:] = [self.n, self.e] bitmap.payload = "\x00" + derPK.encode() der.append(bitmap.encode()) if format == "DER": return der.encode() if format == "PEM": pem = "-----BEGIN %s KEY-----\n" % keyType binaryKey = der.encode() # Each BASE64 line can take up to 64 characters (=48 bytes of data) chunks = [] for i in range(0, len(binaryKey), 48): chunks.append(binascii.b2a_base64(binaryKey[i : i + 48])) pem += "".join(chunks) pem += "-----END %s KEY-----" % keyType return pem if format == "SSH": # Create public key. ssh_rsa = "00000007" + base64.b16encode("ssh-rsa") # Exponent. exponent = "%x" % (self.key.e,) if len(exponent) % 2: exponent = "0" + exponent ssh_rsa += "%08x" % (len(exponent) / 2,) ssh_rsa += exponent modulus = "%x" % (self.key.n,) if len(modulus) % 2: modulus = "0" + modulus if modulus[0] in "89abcdef": modulus = "00" + modulus ssh_rsa += "%08x" % (len(modulus) / 2,) ssh_rsa += modulus return "ssh-rsa %s" % (base64.b64encode(base64.b16decode(ssh_rsa.upper())),) return ValueError("")
def testEncode1(self): # Empty sequence der = DerSequence() self.assertEqual(der.encode(), b('0\x00')) self.assertFalse(der.hasOnlyInts()) # One single-byte integer (zero) der.append(0) self.assertEqual(der.encode(), b('0\x03\x02\x01\x00')) self.assertTrue(der.hasOnlyInts()) # Invariant self.assertEqual(der.encode(), b('0\x03\x02\x01\x00'))
def testEncode1(self): # Empty sequence der = DerSequence() self.assertEqual(der.encode(), b('0\x00')) self.assertFalse(der.hasOnlyInts()) # One single-byte integer (zero) der.append(0) self.assertEqual(der.encode(), b('0\x03\x02\x01\x00')) self.assertTrue(der.hasOnlyInts()) # Invariant self.assertEqual(der.encode(), b('0\x03\x02\x01\x00'))
def testEncode1(self): # Empty sequence der = DerSequence() self.assertEquals(der.encode(), '0\x00') self.failIf(der.hasOnlyInts()) # One single-byte integer (zero) der.append(0) self.assertEquals(der.encode(), '0\x03\x02\x01\x00') self.failUnless(der.hasOnlyInts()) # Invariant self.assertEquals(der.encode(), '0\x03\x02\x01\x00')
def testEncode6(self): # Two integers der = DerSequence() der.append(0x180L) der.append(0xFFL) self.assertEquals(der.encode(), '0\x08\x02\x02\x01\x80\x02\x02\x00\xff') self.failUnless(der.hasOnlyInts()) # der.append(0x01) der[1:] = [9,8] self.assertEquals(len(der),3) self.assertEqual(der[1:],[9,8]) self.assertEqual(der[1:-1],[9]) self.assertEquals(der.encode(), '0\x0A\x02\x02\x01\x80\x02\x01\x09\x02\x01\x08')
def testEncode2(self): # Indexing der = DerSequence() der.append(0) der[0] = 1 self.assertEqual(len(der),1) self.assertEqual(der[0],1) self.assertEqual(der[-1],1) self.assertEqual(der.encode(), b('0\x03\x02\x01\x01')) # der[:] = [1] self.assertEqual(len(der),1) self.assertEqual(der[0],1) self.assertEqual(der.encode(), b('0\x03\x02\x01\x01'))
def testEncode2(self): # Indexing der = DerSequence() der.append(0) der[0] = 1 self.assertEquals(len(der), 1) self.assertEquals(der[0], 1) self.assertEquals(der[-1], 1) self.assertEquals(der.encode(), b('0\x03\x02\x01\x01')) # der[:] = [1] self.assertEquals(len(der), 1) self.assertEquals(der[0], 1) self.assertEquals(der.encode(), b('0\x03\x02\x01\x01'))
def _importKeyDER(self, externKey): """Import an RSA key (public or private half), encoded in DER form.""" try: der = DerSequence() der.decode(externKey, True) # 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(inverse(der[4], der[5])) # Add p^{-1} mod q del der[0] # Remove version return self.construct(der[:]) # Keep on trying PKCS#1, but now for a public key if len(der) == 2: # The DER object is an RSAPublicKey SEQUENCE with two elements if der.hasOnlyInts(): return self.construct(der[:]) # The DER object is a SubjectPublicKeyInfo SEQUENCE with two elements: # an 'algorithm' (or 'algorithmIdentifier') SEQUENCE and a 'subjectPublicKey' BIT STRING. # 'algorithm' takes the value given a few lines above. # 'subjectPublicKey' encapsulates the actual ASN.1 RSAPublicKey element. if der[0] == algorithmIdentifier: bitmap = DerObject() bitmap.decode(der[1], True) if bitmap.isType('BIT STRING') and bord( bitmap.payload[0]) == 0x00: der.decode(bitmap.payload[1:], True) if len(der) == 2 and der.hasOnlyInts(): return self.construct(der[:]) # Try unencrypted PKCS#8 if der[0] == 0: # The second element in the SEQUENCE is algorithmIdentifier. # It must say RSA (see above for description). if der[1] == algorithmIdentifier: privateKey = DerObject() privateKey.decode(der[2], True) if privateKey.isType('OCTET STRING'): return self._importKeyDER(privateKey.payload) except (ValueError, IndexError): pass raise ValueError("RSA key format is not supported")
def testEncode2(self): # One single-byte integer (non-zero) der = DerSequence() der.append(127) self.assertEquals(der.encode(), '0\x03\x02\x01\x7f') # Indexing der[0] = 1 self.assertEquals(len(der),1) self.assertEquals(der[0],1) self.assertEquals(der[-1],1) self.assertEquals(der.encode(), '0\x03\x02\x01\x01') # der[:] = [1] self.assertEquals(len(der),1) self.assertEquals(der[0],1) self.assertEquals(der.encode(), '0\x03\x02\x01\x01')
def _importKeyDER(self, externKey): """Import an RSA key (public or private half), encoded in DER form.""" try: der = DerSequence() der.decode(externKey, True) # 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(inverse(der[4],der[5])) # Add p^{-1} mod q del der[0] # Remove version return self.construct(der[:]) # Keep on trying PKCS#1, but now for a public key if len(der)==2: # The DER object is an RSAPublicKey SEQUENCE with two elements if der.hasOnlyInts(): return self.construct(der[:]) # The DER object is a SubjectPublicKeyInfo SEQUENCE with two elements: # an 'algorithm' (or 'algorithmIdentifier') SEQUENCE and a 'subjectPublicKey' BIT STRING. # 'algorithm' takes the value given a few lines above. # 'subjectPublicKey' encapsulates the actual ASN.1 RSAPublicKey element. if der[0]==algorithmIdentifier: bitmap = DerObject() bitmap.decode(der[1], True) if bitmap.isType('BIT STRING') and bord(bitmap.payload[0])==0x00: der.decode(bitmap.payload[1:], True) if len(der)==2 and der.hasOnlyInts(): return self.construct(der[:]) # Try unencrypted PKCS#8 if der[0]==0: # The second element in the SEQUENCE is algorithmIdentifier. # It must say RSA (see above for description). if der[1]==algorithmIdentifier: privateKey = DerObject() privateKey.decode(der[2], True) if privateKey.isType('OCTET STRING'): return self._importKeyDER(privateKey.payload) except (ValueError, IndexError): pass raise ValueError("RSA key format is not supported")
def pkcs1_v1_5_encode(msg_hash: SHA256.SHA256Hash, emLen: int) -> bytes: # this code is copied from EMSA_PKCS1_V1_5_ENCODE # https://github.com/dlitz/pycrypto/blob/v2.7a1/lib/Crypto/Signature/PKCS1_v1_5.py#L173 digestAlgo = DerSequence([ DerObjectId(msg_hash.oid).encode() ]) #if with_hash_parameters: if True: digestAlgo.append(DerNull().encode()) digest = DerOctetString(msg_hash.digest()) digestInfo = DerSequence([ digestAlgo.encode(), digest.encode() ]).encode() # We need at least 11 bytes for the remaining data: 3 fixed bytes and # at least 8 bytes of padding). if emLen<len(digestInfo)+11: raise TypeError("Selected hash algorith has a too long digest (%d bytes)." % len(digest)) PS = b'\xFF' * (emLen - len(digestInfo) - 3) return b'\x00\x01' + PS + b'\x00' + digestInfo
def sign_bytes_dsa(byte_array, path_to_private_key_pem_file): # Use this method for DSA keys key = open(path_to_private_key_pem_file, 'r').read() # Import the key dsa_key = DSA.importKey(key) # Create a digest of nonce + cnonce # This only seems to work with SHA1 (SHA256 gives us a 401 error) buf = buffer(byte_array) digest = SHA1.new(buf).digest() # Digitally sign the digest with our private key # The corresponding public key is in our admin handle on the server k = random.StrongRandom().randint(1, dsa_key.q-1) sign = dsa_key.sign(digest, k) # Signature bytes from a DSA key need to be DER-encoded # This signature is in two parts (r and s) seq = DerSequence() seq.append(sign[0]) seq.append(sign[1]) return seq.encode()
def sign_bytes_dsa(byte_array, path_to_private_key_pem_file): # Use this method for DSA keys key = open(path_to_private_key_pem_file, 'r').read() # Import the key dsa_key = DSA.importKey(key) # Create a digest of nonce + cnonce # This only seems to work with SHA1 (SHA256 gives us a 401 error) buf = buffer(byte_array) digest = SHA1.new(buf).digest() # Digitally sign the digest with our private key # The corresponding public key is in our admin handle on the server k = random.StrongRandom().randint(1, dsa_key.q - 1) sign = dsa_key.sign(digest, k) # Signature bytes from a DSA key need to be DER-encoded # This signature is in two parts (r and s) seq = DerSequence() seq.append(sign[0]) seq.append(sign[1]) return seq.encode()
def CRYPTO_EMSA_PKCS1_V1_5_ENCODE(M, emLen): msg_hash = SHA256.new(M) digestAlgo = DerSequence([DerObjectId(msg_hash.oid).encode()]) print(digestAlgo) digestAlgo.append(DerNull().encode()) digest = DerOctetString(msg_hash.digest()) digestInfo = DerSequence([digestAlgo.encode(), digest.encode()]).encode() print("%x" % int.from_bytes(digestInfo, byteorder='big')) print("%x" % int.from_bytes(digestAlgo.encode(), byteorder='big')) print("%x" % int.from_bytes(digest.encode(), byteorder='big')) print("%x" % int.from_bytes(msg_hash.digest(), byteorder='big')) #b91d0b7a09f57c109926a449647283adb5dc213c0fdb0cf2b219e064cc132273 2004 00 0501020403650148866009060d30 3130 # 501020403650148866009060d30 #b91d0b7a09f57c109926a449647283adb5dc213c0fdb0cf2b219e064cc132273 2004 #b91d0b7a09f57c109926a449647283adb5dc213c0fdb0cf2b219e064cc132273 #b91d0b7a09f57c109926a449647283adb5dc213c0fdb0cf2b219e064cc1322732004000501020403650148866009060d30313000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0100 #3031 300d06096086480165030402010500 0420 732213cc64e019b2f20cdb0f3c21dcb5ad83726449a42699107cf5097a0b1db9 # 300d06096086480165030402010500 # 0420 732213cc64e019b2f20cdb0f3c21dcb5ad83726449a42699107cf5097a0b1db9 # 732213cc64e019b2f20cdb0f3c21dcb5ad83726449a42699107cf5097a0b1db9 #0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003031300d060960864801650304020105000420732213cc64e019b2f20cdb0f3c21dcb5ad83726449a42699107cf5097a0b1db9 # We need at least 11 bytes for the remaining data: 3 fixed bytes and # at least 8 bytes of padding). if emLen < len(digestInfo) + 11: raise TypeError( "Selected hash algorith has a too long digest (%d bytes)." % len(digest)) PS = b'\xFF' * (emLen - len(digestInfo) - 3) out = b'\x00\x01' + PS + b'\x00' + digestInfo print("%x" % int.from_bytes(out, byteorder='big')) return out
def testEncode4(self): # One very long integer der = DerSequence() der.append(2**2048) self.assertEqual(der.encode(), b('0\x82\x01\x05')+ b('\x02\x82\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00'))
def testEncode6(self): # Two positive integers der = DerSequence() der.append(0x180) der.append(0xFF) self.assertEqual(der.encode(), b('0\x08\x02\x02\x01\x80\x02\x02\x00\xff')) self.assertTrue(der.hasOnlyInts()) self.assertTrue(der.hasOnlyInts(False)) # Two mixed integers der = DerSequence() der.append(2) der.append(-2) self.assertEqual(der.encode(), b('0\x06\x02\x01\x02\x02\x01\xFE')) self.assertEqual(der.hasInts(), 1) self.assertEqual(der.hasInts(False), 2) self.assertFalse(der.hasOnlyInts()) self.assertTrue(der.hasOnlyInts(False)) # der.append(0x01) der[1:] = [9,8] self.assertEqual(len(der),3) self.assertEqual(der[1:],[9,8]) self.assertEqual(der[1:-1],[9]) self.assertEqual(der.encode(), b('0\x09\x02\x01\x02\x02\x01\x09\x02\x01\x08'))
INTEGER modulus INTEGER exponent ''' 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+")
def testEncode5(self): # One single-byte integer (looks negative) der = DerSequence() der.append(0xFFL) self.assertEquals(der.encode(), '0\x04\x02\x02\x00\xff')
def testEncode3(self): # One multi-byte integer (non-zero) der = DerSequence() der.append(0x180L) self.assertEquals(der.encode(), '0\x04\x02\x02\x01\x80')
def exportKey(self, format='PEM', passphrase=None, pkcs=1): """Export this RSA key. :Parameter format: The format to use for wrapping the key. - *'DER'*. Binary encoding, always unencrypted. - *'PEM'*. Textual encoding, done according to `RFC1421`_/`RFC1423`_. Unencrypted (default) or encrypted. - *'OpenSSH'*. Textual encoding, done according to OpenSSH specification. Only suitable for public keys (not private keys). :Type format: string :Parameter passphrase: In case of PEM, the pass phrase to derive the encryption key from. :Type passphrase: string :Parameter pkcs: The PKCS standard to follow for assembling the key. You have two choices: - with **1**, the public key is embedded into an X.509 `SubjectPublicKeyInfo` DER SEQUENCE. The private key is embedded into a `PKCS#1`_ `RSAPrivateKey` DER SEQUENCE. This mode is the default. - with **8**, the private key is embedded into a `PKCS#8`_ `PrivateKeyInfo` DER SEQUENCE. This mode is not available for public keys. PKCS standards are not relevant for the *OpenSSH* format. :Type pkcs: integer :Return: A byte string with the encoded public or private half. :Raise ValueError: When the format is unknown. .. _RFC1421: http://www.ietf.org/rfc/rfc1421.txt .. _RFC1423: http://www.ietf.org/rfc/rfc1423.txt .. _`PKCS#1`: http://www.ietf.org/rfc/rfc3447.txt .. _`PKCS#8`: http://www.ietf.org/rfc/rfc5208.txt """ if passphrase is not None: passphrase = tobytes(passphrase) if format=='OpenSSH': eb = long_to_bytes(self.e) nb = long_to_bytes(self.n) if bord(eb[0]) & 0x80: eb=bchr(0x00)+eb if bord(nb[0]) & 0x80: nb=bchr(0x00)+nb keyparts = [ b('ssh-rsa'), eb, nb ] keystring = b('').join([ struct.pack(">I",len(kp))+kp for kp in keyparts]) return b('ssh-rsa ')+binascii.b2a_base64(keystring)[:-1] # DER format is always used, even in case of PEM, which simply # encodes it into BASE64. der = DerSequence() if self.has_private(): keyType= { 1: 'RSA PRIVATE', 8: 'PRIVATE' }[pkcs] der[:] = [ 0, self.n, self.e, self.d, self.p, self.q, self.d % (self.p-1), self.d % (self.q-1), inverse(self.q, self.p) ] if pkcs==8: derkey = der.encode() der = DerSequence([0]) der.append(algorithmIdentifier) der.append(DerObject('OCTET STRING', derkey).encode()) else: keyType = "PUBLIC" der.append(algorithmIdentifier) bitmap = DerObject('BIT STRING') derPK = DerSequence( [ self.n, self.e ] ) bitmap.payload = bchr(0x00) + derPK.encode() der.append(bitmap.encode()) if format=='DER': return der.encode() if format=='PEM': pem = b("-----BEGIN " + keyType + " KEY-----\n") objenc = None if passphrase and keyType.endswith('PRIVATE'): # We only support 3DES for encryption import Crypto.Hash.MD5 from Crypto.Cipher import DES3 from Crypto.Protocol.KDF import PBKDF1 salt = self._randfunc(8) key = PBKDF1(passphrase, salt, 16, 1, Crypto.Hash.MD5) key += PBKDF1(key+passphrase, salt, 8, 1, Crypto.Hash.MD5) objenc = DES3.new(key, Crypto.Cipher.DES3.MODE_CBC, salt) pem += b('Proc-Type: 4,ENCRYPTED\n') pem += b('DEK-Info: DES-EDE3-CBC,') + binascii.b2a_hex(salt).upper() + b('\n\n') binaryKey = der.encode() if objenc: # Add PKCS#7-like padding padding = objenc.block_size-len(binaryKey)%objenc.block_size binaryKey = objenc.encrypt(binaryKey+bchr(padding)*padding) # Each BASE64 line can take up to 64 characters (=48 bytes of data) chunks = [ binascii.b2a_base64(binaryKey[i:i+48]) for i in range(0, len(binaryKey), 48) ] pem += b('').join(chunks) pem += b("-----END " + keyType + " KEY-----") return pem return ValueError("Unknown key format '%s'. Cannot export the RSA key." % format)
def testEncode5(self): # One single-byte integer (looks negative) der = DerSequence() der.append(0xFF) self.assertEqual(der.encode(), b('0\x04\x02\x02\x00\xff'))
def testEncode3(self): # One multi-byte integer (non-zero) der = DerSequence() der.append(0x180) self.assertEquals(der.encode(), b('0\x04\x02\x02\x01\x80'))
def _EMSA_PKCS1_V1_5_ENCODE(msg_hash, emLen, with_hash_parameters=True): """ Implement the ``EMSA-PKCS1-V1_5-ENCODE`` function, as defined in PKCS#1 v2.1 (RFC3447, 9.2). ``_EMSA-PKCS1-V1_5-ENCODE`` actually accepts the message ``M`` as input, and hash it internally. Here, we expect that the message has already been hashed instead. :Parameters: msg_hash : hash object The hash object that holds the digest of the message being signed. emLen : int The length the final encoding must have, in bytes. with_hash_parameters : bool If True (default), include NULL parameters for the hash algorithm in the ``digestAlgorithm`` SEQUENCE. :attention: the early standard (RFC2313) stated that ``DigestInfo`` had to be BER-encoded. This means that old signatures might have length tags in indefinite form, which is not supported in DER. Such encoding cannot be reproduced by this function. :Return: An ``emLen`` byte long string that encodes the hash. """ # First, build the ASN.1 DER object DigestInfo: # # DigestInfo ::= SEQUENCE { # digestAlgorithm AlgorithmIdentifier, # digest OCTET STRING # } # # where digestAlgorithm identifies the hash function and shall be an # algorithm ID with an OID in the set PKCS1-v1-5DigestAlgorithms. # # PKCS1-v1-5DigestAlgorithms ALGORITHM-IDENTIFIER ::= { # { OID id-md2 PARAMETERS NULL }| # { OID id-md5 PARAMETERS NULL }| # { OID id-sha1 PARAMETERS NULL }| # { OID id-sha256 PARAMETERS NULL }| # { OID id-sha384 PARAMETERS NULL }| # { OID id-sha512 PARAMETERS NULL } # } # # Appendix B.1 also says that for SHA-1/-2 algorithms, the parameters # should be omitted. They may be present, but when they are, they shall # have NULL value. digestAlgo = DerSequence([ DerObjectId(msg_hash.oid).encode() ]) if with_hash_parameters: digestAlgo.append(DerNull().encode()) digest = DerOctetString(msg_hash.digest()) digestInfo = DerSequence([ digestAlgo.encode(), digest.encode() ]).encode() # We need at least 11 bytes for the remaining data: 3 fixed bytes and # at least 8 bytes of padding). if emLen<len(digestInfo)+11: raise TypeError("Selected hash algorith has a too long digest (%d bytes)." % len(digest)) PS = b'\xFF' * (emLen - len(digestInfo) - 3) return b'\x00\x01' + PS + b'\x00' + digestInfo