Hi thank you for the reply. Actually I am using Tauri with react, the data comes from react frontend to the Tauri sign-data function, in Rust code it just sign and send the signature, and from react side the same data(passed to this function) was sent to python server. Let me share what i did so far.
#[tauri::command]
fn sign_data(data: String) -> Result<String, String> {
let secret_path = dirs::data_dir()
.ok_or("Failed to retrieve data directory")?
.join("my-secrets");
let keyfile_path = secret_path.join("keyfile.pem");
let keyfile_path2 = secret_path.join("pub_keyfile.pem");
let private_key_pem = fs::read_to_string(&keyfile_path)
.map_err(|e| format!("Failed to read private key: {}", e))?;
let pub_key_pem = fs::read_to_string(&keyfile_path2)
.map_err(|e| format!("Failed to read public key: {}", e))?;
let private_key = RsaPrivateKey::from_pkcs1_pem(&private_key_pem)
.map_err(|e| format!("Failed to parse private key: {}", e))?;
let padding_scheme = Pkcs1v15Sign::new_unprefixed();
let signature = private_key.sign(padding_scheme.clone(),data.clone().as_bytes()).expect("Failed to sign");
// Test Verification
let public_key = RsaPublicKey::from_pkcs1_pem(&pub_key_pem)
.map_err(|e| format!("Failed to parse public key: {}", e))?;
let verification_result = public_key.verify(padding_scheme, data.as_bytes(), &signature);
println!("{:?}", data);
match verification_result {
Ok(())=>{
println!("Data Verfied");
println!("Signature: {:?}", signature);
},
Err(err)=>println!("Verfication Failed"),
};
Ok(base64::encode(signature))
}
In this rust function written in Tauri, I expect a String data as a message to sign, I load the private key written in pem file, sign the data, and return the signature as base64 encoding>
const getSignedData = async(data)=>{
return Promise.resolve(await window.__TAURI__.invoke("sign_data", {data: data}));
}
const fetchData=(my_data) => {
let data = JSON.stringify({...my_data});
let url = my_python_server_url;
getSignedData(data).then((resp)=>{
// Here i get the sign from sign-data function in rust invoked by tauri, and send the same message as original_data that i passed to create the signature
axios.post(url, {"data": resp[0], "original_data": data}).then((resp)=>{})
}
}
Hope this helps, to see what I am doing.
I am sharing my python code below to verify the sign:
def verify_terminal_request(data):
public_key_str = my_public_key (loaded from db as string)
key = public_key_str.encode('utf-8')
public_key = serialization.load_pem_public_key(key, backend=default_backend())
signed_data = data.get('data')
signed_data = base64.b64decode(signed_data)
# Verify the signature
try:
algorithm = hashes.SHA256()
padding_scheme = padding.PKCS1v15()
public_key.verify(
signature=signed_data,
data=data.get('original_data').encode('utf-8'),
padding=padding_scheme,
algorithm=algorithm
)
return True
except Exception as e:
return False
When i verify the sign using Rust itself, its rsa crate, RsaPublicKey.verify function, it works perfect (as you could see, i added the verification function in rust as well). However samething not working in python.
I am thinking about the padding scheme and the algorithm, in python we need to use the adding scheme and algorithm to verify the signature. In rust we dont define any algorithm when create the sign. And for padding in Rust I use
let padding_scheme = Pkcs1v15Sign::new_unprefixed();
as you could see in the code. I doubt something is mismtached there? But I am not sure and i dont know where is the issue.