예제 #1
0
    def sign(self, data):
        privateKeyNum = bytesToNumber(self.rawPrivateKey)
        hash = Digest.SHA256(data)
        g = generator_256
        n = g.order()
        x = bytesToNumber(self.rawPublicKey[:32])
        y = bytesToNumber(self.rawPublicKey[32:])
        pubkey = Public_key(g, Point(g.curve(), x, y))
        privkey = Private_key(pubkey, privateKeyNum)

        # Generating random nonce k per FIPS 186-3 B.5.1:
        # (except we use 32 extra bytes instead of 8 before reduction)
        # Random bytes taken from os.urandom as well as HMAC(privkey,hash)
        # REVIEW THIS CAREFULLY!!!  CHANGE AT YOUR PERIL!!!

        # 64 random bytes and HMAC(rawPrivateKey,hash) are used as key for an
        # HMAC PRF to generate a 64-byte value which is reduced modulo
        # n to produce the nonce
        #
        # The use of HMAC(rawPrivateKey,hash) means this construction
        # will be secure even if os.urandom fails, however we include
        # os.urandom anyways out of an excess of caution
        randBytes0 = bytearray(os.urandom(64))
        randBytes0 += Digest.HMAC_SHA256(self.rawPrivateKey, hash)
        randBytes = Digest.HMAC_SHA256(randBytes0, bytearray([1]))
        randBytes += Digest.HMAC_SHA256(randBytes0, bytearray([2]))
        c = bytesToNumber(randBytes)
        k = (c % (n - 1)) + 1
        hashNum = bytesToNumber(hash)
        sig = privkey.sign(hashNum, k)
        sigBytes = numberToBytes(sig.r, 32) + numberToBytes(sig.s, 32)
        # Double-check the signature before returning
        assert (Python_ECPublicKey(self.rawPublicKey).verify(data, sigBytes))
        return sigBytes
예제 #2
0
    def sign(self, data):
        ecdsa_sig = None
        try:
            # Hash and apply ECDSA
            hashBuf = bytesToC(Digest.SHA256(data))
            ecdsa_sig = o.ECDSA_do_sign(hashBuf, 32, self.ec_key)

            # Encode the signature into 64 bytes
            rBuf = bytesToC(bytearray(32))
            sBuf = bytesToC(bytearray(32))

            rLen = o.BN_bn2bin(ecdsa_sig.contents.r, rBuf)
            sLen = o.BN_bn2bin(ecdsa_sig.contents.s, sBuf)

            rBytes = bytearray(32 - rLen) + cToBytes(rBuf)[:rLen]
            sBytes = bytearray(32 - sLen) + cToBytes(sBuf)[:sLen]
            sigBytes = rBytes + sBytes
            assert (len(sigBytes) == 64)
        finally:
            if ecdsa_sig:
                o.ECDSA_SIG_free(ecdsa_sig)

        # Double-check the signature before returning
        assert (OpenSSL_ECPublicKey(self.rawPublicKey).verify(data, sigBytes))
        return sigBytes
예제 #3
0
 def _encryptKey(self, password, salt, iter_count, public_key, private_key):
     encKey, authKey = self._deriveKeys(password, salt, iter_count)
     ciphertext = AES(encKey,
                      bytearray(16)).encrypt(private_key.getRawKey())
     macData = ciphertext + public_key.getRawKey()
     mac = Digest.HMAC_SHA256(authKey, macData)
     return ciphertext, mac
예제 #4
0
파일: PBKDF2.py 프로젝트: morristech/TACKpy
    def hmac_sha256(password, salt, iter_count):
        m = salt + bytearray([0, 0, 0, 1])
        result = bytearray(32)
        for c in range(iter_count):
            m = Digest.HMAC_SHA256(bytearray(password, "ascii"), m)
            result = PBKDF2._xorbytes(m, result)

        return result
예제 #5
0
 def _encrypt(self, password):
     encKey, authKey = self._deriveKeys(password, self.salt,
                                        self.iter_count)
     ciphertext = AES.create(encKey, bytearray(16)).encrypt(
         self.private_key.getRawKey())
     macData = ciphertext + self.public_key.getRawKey()
     mac = Digest.HMAC_SHA256(authKey, macData)
     self.ciphertext = ciphertext
     self.mac = mac
예제 #6
0
    def _decrypt(self, password):
        encKey, authKey = self._deriveKeys(password, self.salt,
                                           self.iter_count)
        macData = self.ciphertext + self.public_key.getRawKey()
        calcMac = Digest.HMAC_SHA256(authKey, macData)

        if not Util.constTimeCompare(calcMac, self.mac):
            raise InvalidPasswordException("Bad password")

        return AES.create(encKey, bytearray(16)).decrypt(self.ciphertext)
예제 #7
0
 def verify(self, data, signature):
     assert(len(signature) == 64)
     hashNum = bytesToNumber(Digest.SHA256(data))
     g = generator_256  
     x = bytesToNumber(self.rawPublicKey[ : 32])
     y = bytesToNumber(self.rawPublicKey[32 : ])        
     pubkey = Public_key(g, Point(g.curve(), x,y))
     sig = Signature(bytesToNumber(signature[:32]), 
                     bytesToNumber(signature[32:]))
     return pubkey.verifies(hashNum, sig)        
예제 #8
0
    def getSignature(self, data):
        # Produce ASN.1 signature
        hash = Digest.SHA256(data)
        asn1SigBytes = self.ec.sign_dsa_asn1(hash)

        # Convert stupid ASN.1 signature into 64-byte signature
        # Double-check before returning
        sigBytes = self._convertToRawSignature(asn1SigBytes)

        assert (ECPublicKey(self.rawPublicKey, self.ec).verify(data, sigBytes))
        return sigBytes
예제 #9
0
    def verify(self, data, signature):
        assert (len(signature) == 64)
        ecdsa_sig = None

        try:
            # Create ECDSA_SIG
            ecdsa_sig = o.ECDSA_SIG_new()
            rBuf = bytesToC(signature[:32])
            sBuf = bytesToC(signature[32:])
            o.BN_bin2bn(rBuf, 32, ecdsa_sig.contents.r)
            o.BN_bin2bn(sBuf, 32, ecdsa_sig.contents.s)

            # Hash and verify ECDSA
            hashBuf = bytesToC(Digest.SHA256(data))
            retval = o.ECDSA_do_verify(hashBuf, 32, ecdsa_sig, self.ec_key)
            if retval == 1:
                return True
            elif retval == 0:
                return False
            else:
                assert (False)
        finally:
            if ecdsa_sig:
                o.ECDSA_SIG_free(ecdsa_sig)
예제 #10
0
 def getFingerprint(self):
     digest = Digest.SHA256(self.rawPublicKey)
     assert (len(digest) == 32)
     s = b2a_base32(digest).lower()[:25]
     return "%s.%s.%s.%s.%s" % (s[:5], s[5:10], s[10:15], s[15:20],
                                s[20:25])
예제 #11
0
 def _deriveKeys(self, password, salt, iter_count):
     assert (iter_count > 0)
     masterKey = PBKDF2.hmac_sha256(password, salt, iter_count)
     encKey = Digest.HMAC_SHA256(masterKey, bytearray([1]))
     authKey = Digest.HMAC_SHA256(masterKey, bytearray([2]))
     return encKey, authKey
예제 #12
0
    def __init__(self, data=None):
        if data is None:
            return
        #self.key_sha256 = bytearray(32)
        #self.cert_sha256 = bytearray(32)
        self.notAfter = 0

        # Below values are populated for TACK certs
        self.tackExt = None

        # Below values hold cert contents excluding TACK stuff
        self.preExtBytes = None
        self.extBytes = None
        self.postExtBytes = None

        p = ASN1Parser(data)

        #Get the tbsCertificate
        tbsCertificateP = p.getChild(0)

        #Is the optional version field present?
        #This determines which index the key is at
        if tbsCertificateP.value[0] == 0xA0:
            subjectPublicKeyInfoIndex = 6
            validityIndex = 4
        else:
            subjectPublicKeyInfoIndex = 5
            validityIndex = 3
            #Get the subjectPublicKeyInfo
        spkiP = tbsCertificateP.getChild(subjectPublicKeyInfoIndex)

        #Parse the notAfter time
        validityP = tbsCertificateP.getChild(validityIndex)
        notAfterP = validityP.getChild(1)
        if notAfterP.type == 0x17:  # UTCTime
            self.notAfter = Time.parseASN1UTCTime(notAfterP.value)
        elif notAfterP.type == 0x18:  # GeneralizedTime
            self.notAfter = Time.parseASN1GeneralizedTime(notAfterP.value)
        else:
            raise SyntaxError()

        # Get the hash values
        self.cert_sha256 = Digest.SHA256(data)
        self.key_sha256 = Digest.SHA256(spkiP.getTotalBytes())

        # Check if this is a TACK certificate:
        #Get the tbsCertificate
        versionP = tbsCertificateP.getChild(0)
        if versionP.type != 0xA0:  # i.e. tag of [0], version
            return  # X.509 version field not present
        versionPP = versionP.getTagged()
        if versionPP.value != bytearray([0x02]):
            return  # X.509 version field does not equal v3

        # Find extensions element
        x = 0
        while 1:
            certFieldP = tbsCertificateP.getChild(x)
            if not certFieldP:
                raise SyntaxError("X.509 extensions not present")
            if certFieldP.type == 0xA3:  # i.e. tag of [3], extensions
                break
            x += 1

        self.preExtBytes = data[versionP.offset:certFieldP.offset]
        self.extBytes = bytearray()

        # Iterate through extensions
        x = 0
        certFieldPP = certFieldP.getTagged()
        while 1:
            extFieldP = certFieldPP.getChild(x)
            if not extFieldP:
                break

            # Check the extnID and parse out TACK if present
            extnIDP = extFieldP.getChild(0)
            if extnIDP.value == TlsCertificate.OID_TACK:
                if self.tackExt:
                    raise SyntaxError("More than one TACK Extension")

                    # OK! We found a TACK, parse it..
                self.tackExt = TackExtension(extFieldP.getChild(1).value)
            else:
                # Collect all non-TACK extensions:
                self.extBytes += data[extFieldP.offset :\
                extFieldP.offset + extFieldP.getTotalLength()]
            x += 1

            # Finish copying the tail of the certificate
        self.postExtBytes = data[certFieldP.offset +
                                 certFieldP.getTotalLength():]
예제 #13
0
    def verify(self, data, signature):
        # Convert 64-byte signature into a stupid ASN.1 signature
        asn1SigBytes = self._convertToAsn1Signature(signature)
        hash = Digest.SHA256(data)

        return self.ec.verify_dsa_asn1(hash, asn1SigBytes)