I am working on making a basic password keeper in Golang and want to be able to store the passwords encrypted using RSA. My encryption function and decryption functions both work and will encrypt and decrypt correctly. However after storing the password in a file and then reading the password back from the file the decryption function fails. I have checked to make sure that the reading in of the RSA key is correct and that is not my problem as reading in the RSA key works correctly.
Here is how I am writing my encrypted password to the file
ioutil.WriteFile(filename, encPassword, 0644)
and here is how I am reading back the password
encrypted, err = ioutil.ReadFile(encryptedFileName)
When I run my program I am currently receiving this error code
failed in decrypt_oaep: crypto/rsa: decryption error
exit status 1
My belief is that Read or Write file is adding something to the contents of the file because if I try and decrypt the password before the encrypted password is written or read from a file it will work fine. Any help would be appreciated.
If you need more code I can post more of it later.
Edit: here is a link to codeshare with my entire code: https://codeshare.io/PtMxk
In line 167 you are calling your encrypt function with label = []byte(product).
In line 120 you are calling your decrypt function with a label variable that has been defined but not initialized (i.e. you are sending an empty byte array)
decrypted = decrypt_oaep(private_key, encrypted, label)
Because of that, your decryption won't work. From the docs:
The label parameter must match the value given when encrypting
- https://golang.org/pkg/crypto/rsa/#DecryptOAEP
Solution:
In the decryption call (line 120) send []byte(product) as the label parameter.
Related
Can PEM_read_X509 function read in a CA cert file with private key properly? is it intelligent enough to handle the private key section? Or it will error out if the .pem file contains the private key?
TLDR: YES
Almost all OpenSSL PEM_read[_bio]_XYZ functions will accept a file (or equivalent) containing other data before and/or after the PEM block of type XYZ, and ignore the other data as long as it's not on the same line(s). This is designed to allow 'comments' that describe the PEM data, but also works for other types of PEM data or just arbitrary data not related to the PEM data at all. In particular PEM_read_X509 will read the first block of type CERTIFICATE, X509 CERTIFICATE, or TRUSTED CERTIFICATE and ignore anything and everything else, including a private key block.
Similarly PEM_read_[algo_or_PKCS8]PrivateKey will read the first block of type [ENCRYPTED|RSA|DSA|EC] PRIVATE KEY and ignore everything else, but fail if you tried to read a specific algorithm and the (first) private key block found was a different type. (It also fails, of course, if a valid block is found but is encrypted by a password and you don't provide the correct password either as an argument or via a callback. And if no valid block is found.)
I'm not sure if by 'CA cert' you mean a cert for a CA, or a cert issued by a CA and for an end-entity like your webserver or mailbox. Except for a personal/local or test CA you or a colleague or your organization set up, most ordinary users should have the certs for one or more CAs but never their privatekeys. And if someone responsible for a real CA like say LetsEncrypt was asking such basic questions on Stackoverflow I would be greatly alarmed and worried over the competence and thus security of that CA.
I am pulling data from a server using this API. In order to get an authToken I need to pass my username and password. The password input description says "Hashed password. May be passed as clear text, or as RSA-encrypted hash
(see above for RSA public key)."
To encrypt the password I am using the below code.
library(openssl)
aqKey <- read_pubkey("public_key.pem")
user_name <- "UserName"
password <- rsa_encrypt(charToRaw(askpass()), aqKey)
pw <- rawToChar(password)
This gives me a string with a bunch of unusable characters that produce a 400 error when used in the URL.
/GetAuthToken?user=USERNAME&encPwd=ˆ Ù\026Õ©1tÐÆ®IßÊ/ÛÅÆwéÙeµèB¾kz–V\t–ü˜ÞO«~=ñcѪÿC'p‰-zòjEü,\r¯eÑ}d‹ã\fÀ\030DR·W\026Â\022‰Å:™¶í©«cózÆlE\032Ï4$é¹Þ,ù«…s\021…–ì\026}h¯~?\nC\021ôj-†\032K}ò\026
If I use base64_encode() or URLencode() on either password or pw I get a 200 status but do not receive a token. This is equivalent to an incorrect password. When I pass the password as plaintext I get a token.
My question is, how should I be formatting the password once it has been encrypted so that the server will recognize it as an encrypted password?
How to decrypt the encrypted php code with following:
eval(key_variable(base64_decode('some text')));
this used a keywords instead of gzinflate.
I'm trying to understand how to save passwords used on my app securely, so the user doesn't have to remember them but at the same time nobody can get them looking at the data from my app.
I imagine the files containing the passwords should be encrypted, my doub is whether the user would have to input a "master password" to retrieve stored passwords or if there is any way so that only my app can retrieve them without any input from the user.
Can my app retrieve the passwords without the user needing to write a master password? How is this done?
On Windows your best solution is to use the Data Protection API, used by Chrome, IE, Remote Desktop Connection, and dozens of other technologies, to encrypt data.
The virtue is that the data is encrypted (in a round-about way) with the user's own Windows password. When the user types their password into Windows, it makes all the "protected" data available.
Features:
the data is encrypted
the user doesn't have to enter their password to encrypt data
only the user can ever decrypt it
the user does not have to enter their password to decrypt data
Sample pseudo-code
The API you want is CryptProtectData and CryptUnprotectData:
public bytes[] ProtectBytes(bytes[] plaintext)
{
DATA_BLOB dataIn;
dataIn.cbData = plaintext.Length;
dataIn.pbData = Addr(plaintext[0]);
DATA_BLOB dataOut;
BOOL bRes = CryptProtectData(
dataIn,
null, //data description (optional PWideChar)
null, //optional entropy (PDATA_BLOB)
null, //reserved
null, //prompt struct
CRYPTPROTECT_UI_FORBIDDEN,
ref dataOut);
if (!bRes) then
{
DWORD le = GetLastError();
throw new Win32Error(le, "Error calling CryptProtectData");
}
//Copy ciphertext from dataOut blob into an actual array
bytes[] result;
SetLength(result, dataOut.cbData);
CopyMemory(dataOut.pbData, Addr(result[0]), dataOut.cbData);
//When you have finished using the DATA_BLOB structure, free its pbData member by calling the LocalFree function
LocalFree(HANDLE(dataOut.pbData)); //LocalFree takes a handle, not a pointer. But that's what the SDK says.
}
Later, when you need to decrypt the blob, you use CryptProtectData.
The data is (effectively) encrypted with the user's Windows password; and only the person with their Windows password can decrypt it.
Note: Any code released into public domain. No attribution required.
We use SFTP in our project to transfer files over an SSH connection. This is done through java code. Assuming that if for characters like ?, ! etc we need to give the encoded value in the sftp command, we encoded the password in the code and generated the command. But SFTP isn't working with these encoded password now, it accepts the password directly. What could be the issue. Please help.
Example username: xyz password: abc!
We use URLEncoder to encode the username and password.
String username= URLEncoder.encode(username, "UTF-8");
String password = URLEncoder.encode(password, "UTF-8");
After encoding Our code would generate SFTP command as : sftp://xyz:abc%21#10.9.10.9/home/documents/xyz.txt
But this isn't working, Authentication fails with wrong password. Where as manually if we give command sftp://xyz:abc!#10.9.10.9/home/documents/xyz.txt it works.
Please let us know if we are going wrong.
Thanks in advance.
That's not actually an issue. SFTP is a subsystem of SSH, and SSH creates a secure channel upon client connection (similarly to what SSL does but at layer 7): once the secure and encrypted connection is established, your username and password will be sent to the SSH server inside such connection, therefore there is no need to encode them nor to encrypt them.
The SSH server expects to receive your username/password as they are, not pre-processed nor encoded. And you can do that safely with SFTP for the reason explained here above. So no reason to be worried.