Skip to content

Commit

Permalink
switch client side encryption to use sha256 hash algorithm
Browse files Browse the repository at this point in the history
Close #5989

only support sha1 for depreceted read-only usage

use sha256 for new encrypted write operations

Signed-off-by: Matthieu Gallien <matthieu.gallien@nextcloud.com>
  • Loading branch information
mgallien committed Jan 22, 2025
1 parent a66a5cd commit bebf18d
Showing 1 changed file with 35 additions and 4 deletions.
39 changes: 35 additions & 4 deletions src/libsync/clientsideencryption.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,32 @@ QByteArray deprecatedGeneratePassword(const QString& wordlist, const QByteArray&
(const unsigned char *)salt.constData(),// const unsigned char *salt,
salt.size(), // int saltlen,
iterationCount, // int iterations,
EVP_sha1(), // digest algorithm
EVP_sha1(), // deprecated digest algorithm
keyLength, // int keylen,
unsignedData(secretKey)); // unsigned char *out

if (ret != 1) {
qCWarning(lcCse()) << "Failed to generate encryption key";
// Error out?
}

return secretKey;
}

QByteArray deprecatedSha1GeneratePassword(const QString& wordlist, const QByteArray& salt)
{
const auto iterationCount = 600000;
const auto keyStrength = 256;
const auto keyLength = keyStrength / 8;

QByteArray secretKey(keyLength, '\0');

const auto ret = PKCS5_PBKDF2_HMAC(wordlist.toLocal8Bit().constData(), // const char *password,
wordlist.size(), // int password length,
(const unsigned char *)salt.constData(),// const unsigned char *salt,
salt.size(), // int saltlen,
iterationCount, // int iterations,
EVP_sha1(), // deprecated digest algorithm
keyLength, // int keylen,
unsignedData(secretKey)); // unsigned char *out

Expand All @@ -262,7 +287,7 @@ QByteArray generatePassword(const QString& wordlist, const QByteArray& salt)
(const unsigned char *)salt.constData(),// const unsigned char *salt,
salt.size(), // int saltlen,
iterationCount, // int iterations,
EVP_sha1(), // digest algorithm
EVP_sha256(), // digest algorithm
keyLength, // int keylen,
unsignedData(secretKey)); // unsigned char *out

Expand Down Expand Up @@ -1419,7 +1444,7 @@ std::pair<QByteArray, PKey> ClientSideEncryption::generateCSR(const AccountPtr &
return {result, std::move(keyPair)};
}

ret = X509_REQ_sign(x509_req, privateKey, EVP_sha1()); // return x509_req->signature->length
ret = X509_REQ_sign(x509_req, privateKey, EVP_sha256()); // return x509_req->signature->length
if (ret <= 0){
qCWarning(lcCse()) << "Error signing the csr with the private key";
return {result, std::move(keyPair)};
Expand Down Expand Up @@ -1661,13 +1686,19 @@ void ClientSideEncryption::decryptPrivateKey(const AccountPtr &account, const QB
const auto salt = EncryptionHelper::extractPrivateKeySalt(key);

const auto deprecatedPassword = EncryptionHelper::deprecatedGeneratePassword(mnemonic, salt);
const auto deprecatedSha1Password = EncryptionHelper::deprecatedSha1GeneratePassword(mnemonic, salt);
const auto password = EncryptionHelper::generatePassword(mnemonic, salt);

const auto privateKey = EncryptionHelper::decryptPrivateKey(password, key);
if (!privateKey.isEmpty()) {
_privateKey = privateKey;
} else {
_privateKey = EncryptionHelper::decryptPrivateKey(deprecatedPassword, key);
const auto deprecatedSha1PrivateKey = EncryptionHelper::decryptPrivateKey(deprecatedSha1Password, key);
if (!privateKey.isEmpty()) {
_privateKey = deprecatedSha1PrivateKey;
} else {
_privateKey = EncryptionHelper::decryptPrivateKey(deprecatedPassword, key);
}
}

if (!_privateKey.isNull() && checkPublicKeyValidity(account)) {
Expand Down

0 comments on commit bebf18d

Please sign in to comment.