def sign(self, data, keyName, digestAlgorithm = DigestAlgorithm.SHA256): """ Fetch the private key for keyName and sign the data, returning a signature Blob. :param data: Pointer the input byte buffer to sign. :type data: An array type with int elements :param Name keyName: The name of the signing key. :param digestAlgorithm: (optional) the digest algorithm. If omitted, use DigestAlgorithm.SHA256. :type digestAlgorithm: int from DigestAlgorithm :return: The signature Blob. :rtype: Blob """ keyURI = keyName.toUri() if not self.doesKeyExist(keyName, KeyClass.PRIVATE): raise SecurityException( "FilePrivateKeyStorage.sign: private key doesn't exist") # Read the private key. base64Content = None with open(self.nameTransform(keyURI, ".pri")) as keyFile: base64Content = keyFile.read() pkcs8Der = base64.b64decode(base64Content) privateKey = TpmPrivateKey() try: privateKey.loadPkcs8(pkcs8Der) return privateKey.sign(Blob(data, False).toBytes(), digestAlgorithm) except Exception as ex: raise SecurityException("Error in sign: " + str(ex))
def _doImportKey(self, keyName, pkcs8, password): """ A protected method to import an encoded private key with name keyName in PKCS #8 format, possibly password-encrypted. :param Name keyName: The name of the key to use in the TPM. :param pkcs8: The input byte buffer. If the password is supplied, this is a PKCS #8 EncryptedPrivateKeyInfo. If the password is none, this is an unencrypted PKCS #8 PrivateKeyInfo. :type pkcs8: an array which implements the buffer protocol :param password: The password for decrypting the private key, which should have characters in the range of 1 to 127. If the password is supplied, use it to decrypt the PKCS #8 EncryptedPrivateKeyInfo. If the password is None, import an unencrypted PKCS #8 PrivateKeyInfo. :type password: an array which implements the buffer protocol :raises TpmBackEnd.Error: For an error importing the key. """ try: key = TpmPrivateKey() if password != None: key.loadEncryptedPkcs8(pkcs8, password) else: key.loadPkcs8(pkcs8) # Copy the Name. self._keys[Name(keyName)] = key except TpmPrivateKey.Error as ex: raise TpmBackEnd.Error("Cannot import private key: " + str(ex))
def test_save_load(self): for dataSet in self.keyTestData: # Load the key in PKCS #1 format. pkcs1 = base64.b64decode(dataSet.privateKeyPkcs1) key1 = TpmPrivateKey() key1.loadPkcs1(pkcs1) # Save the key in PKCS #1 format. savedPkcs1Key = key1.toPkcs1() self.assertTrue(savedPkcs1Key.equals(Blob(pkcs1))) # Load the key in unencrypted PKCS #8 format. pkcs8 = base64.b64decode(dataSet.privateKeyPkcs8Unencrypted) key8 = TpmPrivateKey() key8.loadPkcs8(pkcs8) # Save the key in unencrypted PKCS #8 format. savedPkcs8Key = key8.toPkcs8() self.assertTrue(savedPkcs8Key.equals(Blob(pkcs8))) password = Blob("password").toBytes() # Load the key in encrypted PKCS #8 format. encryptedPkcs8 = base64.b64decode(dataSet.privateKeyPkcs8) encryptedKey8 = TpmPrivateKey() encryptedKey8.loadEncryptedPkcs8(encryptedPkcs8, password) # Save the key in encrypted PKCS #8 format and resave as unencrypted. savedEncryptedPkcs8Key = encryptedKey8.toEncryptedPkcs8(password) key8 = TpmPrivateKey() key8.loadEncryptedPkcs8(savedEncryptedPkcs8Key, password) resavedPkcs8Key = key8.toPkcs8() self.assertTrue(resavedPkcs8Key.equals(Blob(pkcs8)))
def _doImportKey(self, keyName, pkcs8, password): """ A protected method to import an encoded private key with name keyName in PKCS #8 format, possibly password-encrypted. :param Name keyName: The name of the key to use in the TPM. :param pkcs8: The input byte buffer. If the password is supplied, this is a PKCS #8 EncryptedPrivateKeyInfo. If the password is none, this is an unencrypted PKCS #8 PrivateKeyInfo. :type pkcs8: an array which implements the buffer protocol :param password: The password for decrypting the private key, which should have characters in the range of 1 to 127. If the password is supplied, use it to decrypt the PKCS #8 EncryptedPrivateKeyInfo. If the password is None, import an unencrypted PKCS #8 PrivateKeyInfo. :type password: an array which implements the buffer protocol :raises TpmBackEnd.Error: For an error importing the key. """ try: key = TpmPrivateKey() if password != None: key.loadEncryptedPkcs8(pkcs8, password) else: key.loadPkcs8(pkcs8) except TpmPrivateKey.Error as ex: raise TpmBackEnd.Error("Cannot import private key: " + str(ex)) self._saveKey(keyName, key)
def sign(self, data, keyName, digestAlgorithm=DigestAlgorithm.SHA256): """ Fetch the private key for keyName and sign the data, returning a signature Blob. :param data: Pointer the input byte buffer to sign. :type data: An array type with int elements :param Name keyName: The name of the signing key. :param digestAlgorithm: (optional) the digest algorithm. If omitted, use DigestAlgorithm.SHA256. :type digestAlgorithm: int from DigestAlgorithm :return: The signature Blob. :rtype: Blob """ keyURI = keyName.toUri() if not self.doesKeyExist(keyName, KeyClass.PRIVATE): raise SecurityException( "FilePrivateKeyStorage.sign: private key doesn't exist") # Read the private key. base64Content = None with open(self.nameTransform(keyURI, ".pri")) as keyFile: base64Content = keyFile.read() pkcs8Der = base64.b64decode(base64Content) privateKey = TpmPrivateKey() try: privateKey.loadPkcs8(pkcs8Der) return privateKey.sign( Blob(data, False).toBytes(), digestAlgorithm) except Exception as ex: raise SecurityException("Error in sign: " + str(ex))
def test_rsa_decryption(self): dataSet = self.rsaKeyTestData pkcs8 = base64.b64decode(dataSet.privateKeyPkcs8Unencrypted) key = TpmPrivateKey() key.loadPkcs8(pkcs8) plainText = Blob([0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07]) cipherTextBase64 = ( "i2XNpZ2JbLa4JmBTdDrGmsd4/0C+p+BSCpW3MuPBNe5uChQ0eRO1dvjTnEqwSECY\n" + "38en9JZwcyb0It/TSFNXHlq+Z1ZpffnjIJxQR9HcgwvwQJh6WRH0vu38tvGkGuNv\n" + "60Rdn85hqSy1CikmXCeWXL9yCqeqcP21R94G/T3FuA+c1FtFko8KOzCwvrTXMO6n\n" + "5PNsqlLXabSGr+jz4EwOsSCgPkiDf9U6tXoSPRA2/YvqFQdaiUXIVlomESvaqqZ8\n" + "FxPs2BON0lobM8gT+xdzbRKofp+rNjNK+5uWyeOnXJwzCszh17cdJl2BH1dZwaVD\n" + "PmTiSdeDQXZ94U5boDQ4Aw==\n") cipherText = base64.b64decode(cipherTextBase64) decryptedText = key.decrypt(cipherText) self.assertTrue(decryptedText.equals(plainText))
def test_derive_public_key(self): for dataSet in self.keyTestData: pkcs8 = base64.b64decode(dataSet.privateKeyPkcs8Unencrypted) key = TpmPrivateKey() key.loadPkcs8(pkcs8) # Derive the public key and compare. publicKeyBits = key.derivePublicKey() expected = base64.b64decode(dataSet.publicKeyEncoding) self.assertTrue(publicKeyBits.equals(Blob(expected)))
def deriveEncryptKey(keyBits): """ Derive a new encrypt key from the given decrypt key value. :param Blob keyBits: The key value of the decrypt key (PKCS8-encoded private key). :return: The new encrypt key (DER-encoded public key). :rtype: EncryptKey """ privateKey = TpmPrivateKey() privateKey.loadPkcs8(keyBits.toBytes()) return EncryptKey(privateKey.derivePublicKey())
def decrypt(keyBits, encryptedData, params): """ Decrypt the encryptedData using the keyBits according the encrypt params. :param Blob keyBits: The key value (PKCS8-encoded private key). :param Blob encryptedData: The data to decrypt. :param EncryptParams params: This decrypts according to params.getAlgorithmType(). :return: The decrypted data. :rtype: Blob """ privateKey = TpmPrivateKey() privateKey.loadPkcs8(keyBits.toBytes()) return privateKey.decrypt( encryptedData.toBytes(), params.getAlgorithmType())
def decrypt(keyBits, encryptedData, params): """ Decrypt the encryptedData using the keyBits according the encrypt params. :param Blob keyBits: The key value (PKCS8-encoded private key). :param Blob encryptedData: The data to decrypt. :param EncryptParams params: This decrypts according to params.getAlgorithmType(). :return: The decrypted data. :rtype: Blob """ privateKey = TpmPrivateKey() privateKey.loadPkcs8(keyBits.toBytes()) return privateKey.decrypt(encryptedData.toBytes(), params.getAlgorithmType())
def setPrivateKeyForKeyName(self, keyName, keyType, privateKeyDer): """ Set the private key for the keyName. :param Name keyName: The key name. :param keyType: The KeyType, such as KeyType.RSA. :type keyType: an int from KeyType :param privateKeyDer: The private key DER byte array. :type privateKeyDer: str, or an array type with int elements which is converted to str """ privateKey = TpmPrivateKey() try: privateKey.loadPkcs8(privateKeyDer, keyType) except Exception as ex: raise SecurityException("Error in loadPkcs8: " + str(ex)) self._privateKeyStore[keyName.toUri()] = privateKey
def test_save_load(self): for dataSet in self.keyTestData: # Load the key in PKCS #1 format. pkcs1 = base64.b64decode(dataSet.privateKeyPkcs1) key1 = TpmPrivateKey() key1.loadPkcs1(pkcs1) # Save the key in PKCS #1 format. savedPkcs1Key = key1.toPkcs1() self.assertTrue(savedPkcs1Key.equals(Blob(pkcs1))) pkcs8 = base64.b64decode(dataSet.privateKeyPkcs8Unencrypted) key8 = TpmPrivateKey() key8.loadPkcs8(pkcs8) # Save the key in PKCS #8 format. savedPkcs8Key = key8.toPkcs8() self.assertTrue(savedPkcs8Key.equals(Blob(pkcs8)))