Ssha512 encryption and Base64 encoding and decoding

Recently, a project uses ssha512 encryption and can be verified normally using C + +, PHP, Python and JS. However, when using rust, many tests are unsuccessful,
I guess my method is wrong, but I don't know what the correct method is? I can only continue to study. Which expert can help me?
The encryption method is to use dovecot's ssha512 encryption scheme. The advantage of this encryption is that the password script generated by the same password is different every time, and the original salt value does not need to be known during decryption
SHA based schemes (also see below for libc’s SHA* support):
SHA: SHA1 sum of the password stored in base64.
SSHA: Salted SHA1 sum of the password stored in base64.
SHA256: SHA256 sum of the password stored in base64. (v1.1 and later).
SSHA256: Salted SHA256 sum of the password stored in base64. (v1.2 and later).
SHA512: SHA512 sum of the password stored in base64. (v2.0 and later).
SSHA512: Salted SHA512 sum of the password stored in base64. (v2.0 and later).

The encryption process is to use PHP for example:
Create a 16 bit salt value
$salt1 = urandom(16);
The password + salt value is hashed
After base65 encoding the converted hash value + salt value, it is the password
The front + {ssha512} is only for a system to select multiple encryption methods
$hash1 = "{SSHA512}".base64_ encode(hash('sha512','123Abc@@'.$salt1,true).$salt1);
The decryption process is:
Calculate salt value
Substr ($hash1,9) remove the previous {ssha512}
Base64 decoding
base64_ decode(substr($hash1,9))
All values after 64 bits are taken as new values
$salt02 = substr(base64_decode(substr($hash1,9)),64);
Generate a password according to the calculated salt02 salt value + 123abc @@ password, and then compare it with the original password. If it is the same, the password is valid, otherwise it is invalid.
The front + {ssha512} is only for a system to select multiple encryption methods
$hash02 = "{SSHA512}".base64_ encode(hash('sha512','123Abc@@'.$salt02,true).$salt02);
Verify validity:
if($hash1 = $hash02){
Echo "the password is valid < br >";
Echo "invalid password < br >";

How do I do this verification with rust?
const B64STR: &'static str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
Creating a 16 bit salt value is a random composition of these characters
My password is the password script corresponding to "123abc @". Give several examples for you to test:

My idea is to use Base64:

let password_ =  "{SSHA512}TRfmgQrXqC/DPrd9VtkY1KVD2oUlhUe7XxMfmh1fONXxSywE+3CU1mWseuS9CRimo7f+9nPNQbZKmy2yQDUssFl5d0VjaHNpK2UyNHZuRC8=".to_ string();
let salt = &amp;password_ [9..]; // Remove {ssha512}
println! ("{}",salt);
let salt_ 01_ bytes = base64::decode(salt.to_string()).unwrap();
println! ("salt_01_bytes: {:?}", salt_01_bytes);
let salt_ 02_ tmp_ =  match String::from_ utf8(salt_01_bytes) {
Ok(v) => v ,
Err(e) => {
return Err(StdError {
ret: 201,
MSG: format! ("incorrect password information: {}", e),
println! ("salt_02_tmp_: {:?}", salt_02_tmp_);
let salt_ 02_ tmp_ =  &amp; salt_ 02_ tmp_ [64..]; // Parse the salt value from the original password
println! ("salt_02_tmp_ {:?}", salt_02_tmp_);
//Hash512 the password passed in by the user + analyze the salt value
let passsalt = format! ("{}{}",password , salt_02_tmp_);
let mut hasher = Sha512::new();
hasher.input_ str(passsalt.as_str());
let mut hex = hasher.result_ str();
hex.push_ str(salt_02_tmp_);
let mut pass_ tmp = "{SSHA512}".to_ string();
pass_ tmp.push_ str(base64::encode(hex).as_str());

But an error is reported:
"ret": 201,
"MSG": "incorrect password information: invalid UTF-8 sequence of 1 bytes from index 0",
"data": ""

I also know it's utf8's problem, but how to solve it?

If you are operating over a blob of raw random bytes, they are not going to be valid UTF-8. Don't force them through a String, use Vec<u8> and/or &[u8] instead.

I need to be compatible with the previous password, so I need to convert the vector into a string instead of using from to realize encryption and decryption_ Utf8, how to convert to string manually?

What does "compatible" mean? You are never going to get a valid Rust string from non-UTF-8 bytes, because Rust strings are by definition UTF-8.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.