-
Notifications
You must be signed in to change notification settings - Fork 144
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Secure Cell passphrase API: PyThemis #596
Merged
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add support for passphrase API by extending SCellSeal construction API. It is possible to add via Python's __new__ special method which may return an instance of a diffrent class (typically, more appropriate subclass). We introduce a SCellSealPassphrase subclass with the same API but different implementation of "encrypt" and "decrypt" methods. To make things easier we also add a SecureCellError to provide more contexts in exceptions without making error messages too long. Initially a different syntax was planned: SCellSeal.with_passphrase('a secret') SCellSeal.with_key(binary_master_key) It had a noble idea of maintaining similarity with other languages which do not have named arguments. However, after updating tests and examples this syntax came off as unnatural and non-Pythonic.
Those are mostly straighforward. Also, update existing tests for master key API and ensure that positional arguments to Secure Cell constuctors are interpreted as keys, not passphrases. Another change is update of tests to use a proper master key instead of a fixed password with master key API.
The main showcase has been reworked completely to demonstrate API. Other examples got cosmetic updates to avoid using 'passwords' when in fact they work with master keys.
Lagovas
reviewed
Feb 28, 2020
Instead of forcing the users to do '.encode(...)' calls themselves, adhere to standard Python practice of accepting an "encoding" argument with specified default encoding.
Instead of writing type hacks, use a compatibility library. This should make it easier to convert PyThemis into Python 3-only when we decide to drop Python 2 compatibility. We will need to replace all "six" calls with native equivalents.
I’ve merged PHP PR which enables integration testing of passphrase API between platforms. Now integration tests between Python and PHP are broken 🤔 Okay, tests, just with that you have paid off all effort that has been put into you. However, this also raises some questions:
|
3 tasks
Raise warnings instead of exceptions when we suspect that master key API is misused with strings. Since we're not introducing a new API, it would be rude to break Existing Code with unannounced exceptions. Howerver, we cannot pass on the possible misuse either. Master key API should not be used with strings. Currently, if you pass a Unicode string, it will be encoded in some internal encoding (usually UTF-8, but this may not be the case on Windows). Master key API should not be used with human-readable strings due to security concerns. Produce a warning when we see master key API to be used with types that we previously allowed but no longer recommend. Provide suggestions on what API should be used instead. This warns the user of possible misuse (if they pay attention to warnings) and does not break production code, which will keep the old behavior of misusing strings as master keys.
Lagovas
approved these changes
Mar 16, 2020
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Add support of Secure Cell passphrase API to PyThemis. The API is described in RFC 3.3 (with corrections).
User notes
Passphrase-based interface of Secure Cell allows you to use short and memorable passphrases to secure your data. While symmetric keys are more secure, they are also longer and much harder for humans to remember.
Here is how you can use passphrases with Secure Cell:
Passphrase API accepts passphrases as relatively short strings, suitable for human memory. Master key API uses randomly generated, long binary keys, which are more suitable for machines to remember. However, they are also more efficient and generally more secure due to considerable length. You should prefer to use keys over passphrases if there are no humans involved. The interface is almost the same:
API compatibility
Explicit choice between passphrases and keys
Normally you should use
SCellSeal
constructor for Secure Cell in Seal mode:However, you can also import the
SCellSealPassphrase
class and construct it directly:Only
SCellSeal
supportspassphrase
argument and passphrase encryption.SCellTokenProtect
andSCellContextImprint
work only withkey
.Warnings about master key API misuse
Master keys should be provided as binary data. Previously PyThemis allowed to pass Unicode strings as master keys but this usage is now discouraged. PyThemis will emit warnings if strings are passed to master key API. If you see warnings like
then you should evaluate the call site and apply appropriate change:
bytes
– if you believe that the passphrase is long enough to be securely used as a master key.skeygen.GenerateSymmetricKey()
passphrase=
API – if the secret is going to be entered by a human.Master keys and positional arguments
Previously, Secure Cell could be initialized with master key as a simple positional argument:
This API is still available and supported. However, it is a good idea to explicitly say
key=
orpassphrase=
when usingSCellSeal
unless it is obvious from context.Unicode considerations
Master keys are always binary data (
bytes
). Passphrases may be provided either as Unicode strings (str
) or as encodedbytes
. If you provide a Unicode passphrase it will be encoded in UTF-8 for compatibility with other Themis platforms. If you need a different encoding, please useencoding=
optional parameter, for example:In Python 2 master keys are expected as
str
values and passphrases may be provided either asstr
(raw bytes used as is), or asunicode
(will be encoded in UTF-8 by default, useencoding=
to change). Take care with string encoding.Technical notes
__special__.__python__.__magic__.__with__.__new__ allows us to maintain syntax compatibility and introduce
passphrase=
as an extension. Initially a different syntax was planned:It had a noble idea of maintaining similarity with other languages which do not have named arguments. However, after updating tests and examples this syntax came off as unnatural and non-Pythonic. The Zen of Python says:
So now we have exactly one way to construct a Secure Cell in each mode: via
SCellMode
constructor. (Well, you can also importSCellSealPassphrase
if you like that more.)Note that another language with named arguments (Swift) is also going to get a similar API, so this is sort of a prior example.
Checklist