-
Notifications
You must be signed in to change notification settings - Fork 6
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
libsodium support #2
Comments
I think isolating the crypto and defaulting it to keep the package easy to use. Let me know your thoughts, and I can work on implementing it Here is a quick idea of what I am thinkingstarekrow\lockbox\CryptoKey::Lock()public function Lock( $message )
{
if (!$this->data) {
return false;
}
$cryptoLibrary = $this->getCryptoLibrary()
$ciphertext_raw = $cryptoLibrary->encrypt($message, $this->getEncryptionKey());
$hmac = $cryptoLibrary->generateHmac($ciphertext_raw, $this->getHmacKey());
$ciphertext = base64_encode($iv.$hmac.$ciphertext_raw);
return $ciphertext;
} Interface so anyone can swap it out with their own implementationI was debating if the encryption interface should be separate from the hmac interface. interface CryptoLibraryInterface
{
public function generateRandomBytes($length);
public function encrypt($message);
public function decrypt($message);
public function setEncryptionCipher($cipher);
public function getEncryptionCipher();
public function getEncryptionKeyLength();
public function getEncryptionKey();
public function setEncryptionKey($key);
public function generateHmac($message);
public function isHmacValid($hmac, $message);
public function setHmacAlgorithm($algo);
public function getHmacAlgorithm();
public function getHmacKeyLength();
public function getHmacKey();
public function setHmacKey($key);
} Abstract class to implement common functionsabstract class AbstractCryptoLibrary implements CryptoLibraryInterface
{
private $hmacKey;
private $encryptionKey;
private $cipher;
public function setEncryptionCipher($cipher)
{
$this->cipher = $cipher;
}
public function getEncryptionCipher()
{
return $this->cipher;
}
public function setEncryptionKey($key)
{
$this->encryptionKey = $key;
}
public function getEncryptionKey()
{
if (isset($this->encryptionKey) === false) {
$keyLength = $this->getEncryptionKeyLength();
$key = $this->generateRandomBytes($keyLength);
$this->setEncryptionKey($key);
}
return $this->encryptionKey;
}
public function isHmacValid($hmac, $message) {
return $this->generateHmac($message) === $hmac;
}
//... rest of the common functions
} OpenSSL version:class OpenSSLCryptoLibrary extends AbstractCryptoLibrary
{
public function generateRandomBytes($length)
{
return openssl_random_pseudo_bytes($length);
}
//... rest of the openssl specific functions
} |
Hmm. I think it would work out better to move the abstraction deeper, along these lines: public function hash( $alg, $data );
public function hmac( $alg, $key, $data );
public function hkdf( $alg, $ikm, $len, $salt, $info );
public function encrypt( $alg, $key, $iv, $data );
public function decrypt( $alg, $key, $iv, $data );
public function hashcmp( $h1, $h2 );
public function random( $count ); Just a couple of assumptions (always binary strings, no wierd operational modes) cleans up the interface a lot. This then becomes a useful and clean building block for any number of related problems. It also leaves all the decisions of what to do inside Still need to work out how to handle algorithm names and discovery. It should be as permissive as possible without tolerating ambiguous input. |
FYI all, I'm building this out now. I'm going with a static API and a driver model, should be pretty slick. |
It would be nice to have optional support for libsodium as an alternative to the
openssl
extension, since libsodium is moving into core.This could be hacked in place, or done by isolating the crypto use in CryptoKey. Either way might complicate cipher selection (needs research).
The text was updated successfully, but these errors were encountered: