Encrypt with a specific key and uncrypt with another specific key - encryption

There are some encrypt method that allow I encrypt a string data with a specific unique encode key (write key) and decode it to an another specific decode key (read key)?
For instance: supposing that we have the string Hello World. So we have two keys, one for encoding (like John) and another to decoding (like Doe). So we create an encoded version of string like:
Note: not limited to PHP, it just an easy example for me...
$string = "Hello World";
$encoded = encode($string, "John", "Doe");
//#function encode(string data, string write_key, string read_key);
//#return string "abcdef123456" -- supposing that it is the encoded string!
Now we have the new encoded string of Hello World data as abcdef123456. Now if we try to read this string with the write key we don't will get the original version, but a strange version or just an error like invalid read key.
$decoded = decode($encoded, "John");
//#function decode(string data, string read_key);
//#return false -- invalid read key! or just a strange result data
$decoded = decode($encoded, "Doe");
//#return string "Hello World"
Note: I just need to know if there are some encrypt project like that, but if you know a library, it's ok too. I need it to my project. I know that is possible hash with a key, but the original result never can back. And I know too read-write key encodings, but it doesn't is really what I need.

You are talking about Public key cryptography.
To suggest a library you should specify the language you will be using in your project.

Related

Encrypting user passwords, save secret key to file

I'm trying to make secure keeping users passwords in database. After quick research I decided use ed25519_dalek library.
Important notice:
I plan use this encryption in actix website.
For now steps are simple:
save password in variable,
generate keys,
save secret and public passwords in file(for now),
encrypt password,
save password to database(skipping for now),
I'm stack in third step: saving keys to file.
To be honest I can write passwords to file, but can't read it.
My code below:
use std::io;
use std::io::{BufRead, Write};
use rand::rngs::OsRng;
use ed25519_dalek::{Keypair, PublicKey, Signature, Signer, Verifier};
use ed25519_dalek::{PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH, KEYPAIR_LENGTH, SIGNATURE_LENGTH};
let mut csprng = OsRng{};
let keypair: Keypair = Keypair::generate(&mut csprng);
let password: &[u8] = b"testing_password123!##$%";
let signature: Signature = keypair.sign(password);
assert!(keypair.verify(&password, &signature).is_ok());
For this moment my code works well. I'm getting signature and looks like values password and signature are the same.
I'm trying to deserialize keys:
let public_key_bytes: [u8; PUBLIC_KEY_LENGTH] = keypair.public.to_bytes();
let secret_key_bytes: [u8; SECRET_KEY_LENGTH] = keypair.secret.to_bytes();
let keypair_bytes: [u8; KEYPAIR_LENGTH] = keypair.to_bytes();
let signature_bytes: [u8; SIGNATURE_LENGTH] = signature.to_bytes();
After this, I want to save secret key and public key to different files. But for simplify we want to save only secret key.
My steps below:
use std::fs::File;
use std::io::prelude::*;
use std::path::Path;
let filename = "keys.txt";
let path = Path::new(filename);
let display = path.display();
let mut file = match File::create(&path) {
Err(why) => panic!("Couldn't create {}: {}", display, why),
Ok(file) => file,
};
match file.write_all(&secret_key_bytes) {
Err(why) => panic!("couldn't write to {}: {}", display, why),
Ok(_) => println!("successfully wrote to {}", display),
};
In this step I can write bytes to a file. But... The key has type [u8;32]. Using cat command showing strange things(I understand why).
But I can't read this file. Bytes can't be read like this.
After this entry is time for my question:
How can I change type of secret key [u8;32] to String or str?
My idea is:
Change datatype to String or str and then save to file.
Or maybe I do something wrong or simply is it better way to do this?
I need little push in right way :)
It is unsafe to encrypt and store passwords in a database. Moreover you are planning to store both public and private keys in files. The program requires it to be kept in reach for authenticating, so it won't be hard for someone to find the files with public and private keys. Anyone who have access to those files can access users' passwords including you.
The workaround is to generate a hash from the password and store it in the database. Hashing is a one way process of generating a string from an input string such that the inverse operation is impossible. So,the hash of the user input and the hash in the database is matched to authorize the user. There are a bunch of hashing functions available in RUST including the SHA-2 family hashing functions.
It is still insecure if you are just hashing the passwords and saving them in the database since the hashes of most common passwords and almost all possible words are already available in datasets named hash dictionaries and by using that, anyone who have access to your database can find the password. This technique is called dictionary attack. To prevent it, you can make the input string larger by concatenating with some random characters (salt) with the user input and
store the hash and the salt in the database.

Invalid Header when including customer provided key to upload file to Azure Blob

I'm following this article to include customer provided key when uploading file to Azure Blob. My code is using string key instead of byte[]. I have tried different format of key such as:
Plain text string: "my key"
Base 64 AES 256 encrypted key generated from this link
When I upload file using above customer provided key, it throws "The value for one of the HTTP headers is not in the correnct format". I'm suspecting it is due to the encryption key is not included in the header.
Is my key generated in a correct approach? Or is there any configuration I have missed out?
You can use the following way to generate base 64 encrypted key when you add key as string.
string base64Encoded = "YmFzZTY0IGVuY29kZWQgc3RyaW5n";
byte[] data = System.Convert.FromBase64String(base64Encoded);
For more details, you could refer to this article.

'=' symbol at the end shows encryption

I am using 128-bit Rijndael with ECB cipher mode encryption to convert my string. It formats some kind of string with symbols == or = at the end.
In my code I need some preliminary decision was this string encrypted. Can I suggest that if it contains = symbol at the end it is encrypted or possible cases when I will not get = symbol in the end in encrypted string?
First of all, if you are using ECB you are not really "encrypting" since it is a broken cipher mode (see: http://bobnalice.wordpress.com/2009/01/28/friends-don%E2%80%99t-let-friends-use-ecb-mode-encryption/ )
Secondly, the = signs you are seeing are the Base64 padding characters. They are only tagentially related to encryption since Base64 is used for any kind of binary data, not just encrypted date.
Thirdly, you can't even rely on the = sign always being present for Base64 data... it is only added for certain lengths of data (i.e. you could have encrypted, Base64 data that has no = sign)
As #JoelFan points out, those '=' characters are Base64 padding which aren't part of the encryption at all, and aren't always there either if the data comes out to the right number of characters naturally.
You need to add something "out of band". I would replace the potentially-encrypted string with a class which has a string member for the data, and an "encrypted" flag. Once you're there, throw in a getData() method that checks if the instance's data is encrypted, returns the unencrypted value of the data if so (and may cache the plaintext in a private member for later, if it'll be accessed a lot), or just returns the plain text if it's not encrypted.

Decrypting a string using erlang + RSA

I have two separated applications, one written in Java and other in Erlang.
Both applications send messages to each other in String format, and those messages are encrypted in the Java app and need to be decrypted in the Erlang app.
The problem is this:
I'm using RSA public/private keys to do the encryption/decryption.
If I encrypt the data and decrypt all inside the my Erlang code, everything is fine. But, I'm not able to decrypt the string coming from my java endpoint.
Here's a simple test I'm doing:
PrivKey = "-----BEGIN RSA PRIVATE KEY----- ...",
% Data is the string I receive from Java
Data = "s013aA/SGN2iGYEbEIXXKvJiipqisRVfVEDneL8npRgThTHxTnYZESzVfCF463phPZyo5aOozisU7pwDdGKXgY8aqYZC+a3uES5muTb2RrzJ17yYku+g4S44vgIwZ9EyustZafNVGEYfgbWOYaPP/q5k683uR+MRHVqp6UbqMok=",
[PrivEntry] = public_key:pem_decode(list_to_binary(PrivKey)),
Priv = public_key:pem_entry_decode(PrivEntry),
BinData = iolist_to_binary(Data),
public_key:decrypt_private(Data, Priv).
Executing this code generates an error like this:
** exception error: decrypt_failed
I think the problem is in the format of BinData, but I couldn't find any place saying how I encode a string to pass to decrypt_private function.
Does anyone knows how to do this? This seems simple, but is taking me a lot of time to figure out.
Thanks.
After digging a little bit more, I found the answer!
I needed to decode my string into a base64 binary.
PrivKey = "-----BEGIN RSA PRIVATE KEY----- ...",
% Data is the string I receive from Java
Data = "s013aA/SGN2iGYEbEIXXKvJiipqisRVfVEDneL8npRgThTHxTnYZESzVfCF463phPZyo5aOozisU7pwDdGKXgY8aqYZC+a3uES5muTb2RrzJ17yYku+g4S44vgIwZ9EyustZafNVGEYfgbWOYaPP/q5k683uR+MRHVqp6UbqMok=",
[PrivEntry] = public_key:pem_decode(list_to_binary(PrivKey)),
Priv = public_key:pem_entry_decode(PrivEntry),
BinData = base64:decode(Data), %<-- THIS IS THE MAGIC
public_key:decrypt_private(BinData, Priv).
Hope this helps other people.

Obfuscating a url

I'm working on an asset management website where in whenever an asset is issued to a user the system would send an email notification with a url in it that would show the user all the assets issued to him. I could have used the query string to pass the user ID but again people could abuse it to view assets issued to other users. My client doesn't wants the user to authenticate themselves when they click on the link. So i need something that would hide the parameters being passed in the query string or at least make them obscure. I've read about url encoding, GUID etc. but i'm not sure what to do. I'm just a beginner. Please pardon my ignorance and point me in the right direction.
Taken what you have said, that you're just a beginner, and assuming that this will be public, you can do the easiest way:
Create a new table in your database and called for example tbl_links, as columns just add 3
user_id (foreigner key to the user table)
guid (primary key, unique)
settings (nvarchar(250)
When you need to send an email, create a new row for the user, for example:
Guid guid = Guid.New();
String settings = "date_from:2012/01/01;date_to:2013/01/01";
And insert it one the database, where the link that you put in the email, should have the guid, for example, http://domain.com/info/?g=....
You could append Json to that settings column and parse it into an object again in the code, ask a new question if you want to take this route.
I personally use a security algorithm to pass only the user_id but you did said you're a beginner, so I only showed you the easy and still valid way.
P.S. for security reasons, you should say in the email that your link is only valid for the next 4 hours or so you can prevent people from generating GUIDs in order to try and get some information.... Simple add a create_date column of type datetime and use that to see if the link already expired or not...
For obscuring URL parameters, you want to use a modified Base64 encoding. Please keep in mind that obscurity is not security, and Base64 encoding something does not in any way make anything secure.
If you're intending to use this for authentication purposes, I think you should reconsider. Look into public key encryption and digital signatures as a starting point.
Trying to secure access to a URL is not the right approach. Give the urls away freely and authenticate your users instead.
I would also highly recommend using SSL for serving up this data.
Security through obscurity fails 100% of the time once the obscurity is not longer obscure.
What you can do is to add some prefix and suffix to the id and the encrypt that string. Something like this:
static public string EncodeTo64(string toEncode)
{
byte[] toEncodeAsBytes
= System.Text.ASCIIEncoding.ASCII.GetBytes(toEncode);
string returnValue
= System.Convert.ToBase64String(toEncodeAsBytes);
return returnValue;
}
static public string DecodeFrom64(string encodedData)
{
byte[] encodedDataAsBytes
= System.Convert.FromBase64String(encodedData);
string returnValue =
System.Text.ASCIIEncoding.ASCII.GetString(encodedDataAsBytes);
return returnValue;
}
string prefix = "lhdsjñsdgñdfj";
string suffix = "dfknsfñn3ih";
var strToEncode = prefix + "|" + id + "|" + suffix;
var encoded = EncodeTo64(str);
var decoded = DecodeFrom64(encoded).Split('|');
if( decoded.length != 3 || decoded[0] != prefix || decoded[2] != suffix )
throw new InvalidArgumentException("id");
var decodedId = decoded[1];

Resources