diff --git a/include/opendht/crypto.h b/include/opendht/crypto.h
index 1033c04d99909885f1f225f2594f4597241d7727..1f14771f2b2166ad7f2792cc8e48fabf76a6650b 100644
--- a/include/opendht/crypto.h
+++ b/include/opendht/crypto.h
@@ -793,7 +793,7 @@ OPENDHT_PUBLIC void hash(const uint8_t* data, size_t data_length, uint8_t* hash,
  * that can be transmitted in clear, and will be generated if
  * not provided (32 bytes).
  */
-OPENDHT_PUBLIC Blob stretchKey(const std::string& password, Blob& salt, size_t key_length = 512/8);
+OPENDHT_PUBLIC Blob stretchKey(std::string_view password, Blob& salt, size_t key_length = 512/8);
 
 /**
  * AES-GCM encryption. Key must be 128, 192 or 256 bits long (16, 24 or 32 bytes).
@@ -802,15 +802,37 @@ OPENDHT_PUBLIC Blob aesEncrypt(const uint8_t* data, size_t data_length, const Bl
 OPENDHT_PUBLIC inline Blob aesEncrypt(const Blob& data, const Blob& key) {
     return aesEncrypt(data.data(), data.size(), key);
 }
-OPENDHT_PUBLIC Blob aesEncrypt(const Blob& data, const std::string& password);
+OPENDHT_PUBLIC Blob aesEncrypt(const Blob& data, std::string_view password);
 
 /**
  * AES-GCM decryption.
  */
 OPENDHT_PUBLIC Blob aesDecrypt(const uint8_t* data, size_t data_length, const Blob& key);
 OPENDHT_PUBLIC inline Blob aesDecrypt(const Blob& data, const Blob& key) { return aesDecrypt(data.data(), data.size(), key); }
-OPENDHT_PUBLIC Blob aesDecrypt(const uint8_t* data, size_t data_length, const std::string& password);
-OPENDHT_PUBLIC inline Blob aesDecrypt(const Blob& data, const std::string& password) { return aesDecrypt(data.data(), data.size(), password); }
+OPENDHT_PUBLIC inline Blob aesDecrypt(std::string_view data, const Blob& key) { return aesDecrypt((uint8_t*)data.data(), data.size(), key); }
+
+OPENDHT_PUBLIC Blob aesDecrypt(const uint8_t* data, size_t data_length, std::string_view password);
+OPENDHT_PUBLIC inline Blob aesDecrypt(const Blob& data, std::string_view password) { return aesDecrypt(data.data(), data.size(), password); }
+OPENDHT_PUBLIC inline Blob aesDecrypt(std::string_view data, std::string_view password) { return aesDecrypt((uint8_t*)data.data(), data.size(), password); }
+
+/**
+ * Get raw AES key from password and salt stored with the encrypted data.
+ */
+OPENDHT_PUBLIC Blob aesGetKey(const uint8_t* data, size_t data_length, std::string_view password);
+OPENDHT_PUBLIC Blob inline aesGetKey(const Blob& data, std::string_view password) {
+    return aesGetKey(data.data(), data.size(), password);
+}
+/** Get the salt part of data password-encrypted with `aesEncrypt(data, password)` */
+OPENDHT_PUBLIC Blob aesGetSalt(const uint8_t* data, size_t data_length);
+OPENDHT_PUBLIC Blob inline aesGetSalt(const Blob& data) {
+    return aesGetSalt(data.data(), data.size());
+}
+/** Get the salt part of data password-encrypted with `aesEncrypt(data, password)` */
+OPENDHT_PUBLIC std::string_view aesGetEncrypted(const uint8_t* data, size_t data_length);
+OPENDHT_PUBLIC std::string_view inline aesGetEncrypted(const Blob& data) {
+    return aesGetEncrypted(data.data(), data.size());
+}
+
 
 }
 }
diff --git a/src/crypto.cpp b/src/crypto.cpp
index 578003e2882f0ecb38f3fa5ab0385cda6def9138..49cbc9dea3fa237bde521a591ccefd8b03b55d6b 100644
--- a/src/crypto.cpp
+++ b/src/crypto.cpp
@@ -103,7 +103,7 @@ Blob aesEncrypt(const uint8_t* data, size_t data_length, const Blob& key)
     return ret;
 }
 
-Blob aesEncrypt(const Blob& data, const std::string& password)
+Blob aesEncrypt(const Blob& data, std::string_view password)
 {
     Blob salt;
     Blob key = stretchKey(password, salt, 256 / 8);
@@ -152,16 +152,35 @@ Blob aesDecrypt(const uint8_t* data, size_t data_length, const Blob& key)
     return ret;
 }
 
-Blob aesDecrypt(const uint8_t* data, size_t data_len, const std::string& password)
+Blob aesDecrypt(const uint8_t* data, size_t data_length, std::string_view password)
 {
-    if (data_len <= PASSWORD_SALT_LENGTH)
+    return aesDecrypt(
+        aesGetEncrypted(data, data_length),
+        aesGetKey(data, data_length, password)
+    );
+}
+
+Blob aesGetSalt(const uint8_t* data, size_t data_length)
+{
+    if (data_length <= PASSWORD_SALT_LENGTH)
+        throw DecryptError("Wrong data size");
+    return Blob {data, data+PASSWORD_SALT_LENGTH};
+}
+
+std::string_view aesGetEncrypted(const uint8_t* data, size_t data_length)
+{
+    if (data_length <= PASSWORD_SALT_LENGTH)
         throw DecryptError("Wrong data size");
-    Blob salt {data, data+PASSWORD_SALT_LENGTH};
-    Blob key = stretchKey(password, salt, 256/8);
-    return aesDecrypt(data+PASSWORD_SALT_LENGTH, data_len - PASSWORD_SALT_LENGTH, key);
+    return std::string_view((const char*)(data+PASSWORD_SALT_LENGTH), data_length - PASSWORD_SALT_LENGTH);
+}
+
+Blob aesGetKey(const uint8_t* data, size_t data_length, std::string_view password)
+{
+    Blob salt = aesGetSalt(data, data_length);
+    return stretchKey(password, salt, 256/8);
 }
 
-Blob stretchKey(const std::string& password, Blob& salt, size_t key_length)
+Blob stretchKey(std::string_view password, Blob& salt, size_t key_length)
 {
     if (salt.empty()) {
         salt.resize(PASSWORD_SALT_LENGTH);