I have created an application where I could send a mail with Mail API. Therefore, for that I had to provide the email id and password of the source mailbox.
Refer the code below:
Mail sender = new Mail("sourceEmailID", "sourcePassword");
sender.sendMail("Subject","Body","sourceEmailID", "destinationEmailID");
Now, I dont want to provide the harcoded password inside my source code. Infact I want to convert it into asterisk form or any other secured form.
But the value shouldn't change when calling the original form.
What should I do to for this!
Thanks in advance.
You will need the plain text password in any case while creating Mail Object.
To improve security,
you should:
Encrypt the password and keep it in code/property file/database. Also store the secret key in code/property file/database. Decrypt it at the time of creating Mail object
Use SSL/TLS/https
This should provide you enough security.
Related
Team,
I have an requirement like i have to support to my partner (third party) portal to call us directly by making api call with credentials from their browser.
e.g.) Partner portal browser makes AJAX Call with below:
URL ---> https://example.com/request
HEADER ---> user_id : foo
HEADER ---> password : mypasswd
payload ---> {
"request_time" : 2232876435,
"request_name" : "get_user_info",
...
...
}
And their browser/portal is accessible/used by untrusted users of theirs. So now problem is since the call is from the front end; end user easily can inspect the browser to see the network api calls along with credential we have given to our partner to authorise at our side.
So i am planning to give suggestion to partner by asking them to encrypt the payload and headers in their portal backend server and render the encrypted information in the portal like below.
Encrypt (payload) using mypasswd.
Encrypt (password) using request_time <NOW OPTIONAL TO PASS>
So now,
e.g.) URL ---> https://example.com/request
HEADER ---> user_name : foo
HEADER ---> password : ENCRYPTED<mypasswd> <-- OPTIONAL
payload ---> ENCRYPTED<
{
"request_time" : 2232876435,
"request_name" : "get_user_info",
...
...
}
>
So in our system we will decrypt payload with mypasswd retrieved for user_id foo. so if decryption is successful, then the request is from valid resource.
Now the end portal user cannot understand the request from browser inspection.
NOTES:
I can't suggest my partner to call from their backend.
From the request payload i can identify repeated same request through unique transaction id, so they can't resubmit the same request. Hence avoiding replay attack.
Questions:
Q1) Any flaw or suggestion on this solution?
Q2) Is it possible to identify the decryption using passphrase is success or not in java? I am new to encryption, so could you please share any code or link to achieve this?
yours thoughts much valuable to me.
TLDR:
References:
Basic encryption details
https://blog.storagecraft.com/5-common-encryption-algorithms/
https://www.veracode.com/blog/research/encryption-and-decryption-java-cryptography
https://gooroo.io/GoorooTHINK/Article/13023/The-difference-between-encryption-hashing-and-salting/2085#.W2L_KdgzZD0
Java Encryption
How to encrypt and decrypt String with my passphrase in Java (Pc not mobile platform)?
Java Security: Illegal key size or default parameters?
Identifying decryption is successful through this exception:
Given final block not properly padded
EDIT: I misunderstood the question. If the information is encrypted by the third party before it reaches the end-user then this approach is generally safe. Replay attacks are the main thing to look out for. If the request being made is idempotent then you don't really need to worry, but otherwise you might need to implement a short-lived database for used tokens along with an expiry time or something similar.
You are solving this problem the wrong way. Having the end user make this request to you on behalf of the third party is silly - if the request comes from their browser then by definition they control the information they are sending and the way it is sent. Encryption does nothing to solve this since the encryption logic is also client side.
The solution to this problem is to eliminate the end-user. The request should come directly from the third party to you. This might be from the end-user making a request to the third party API or it might not - it doesn't matter.
In the login service, a user is posting a json as payload to a Spring RESTful login service like below:
{
"username": "john",
"password": "doe"
}
Once the Spring RESTful service receives the call, it compares the password with the one store in the database in plain text.
I see two problems in the current implementation.
The password is sent through HTTP as a POST payload in plain text.
The correct password stored in the database is in plain text.
For issue 2, I decided to use bcrypt to encrypt the password stored in the database as mentioned in this post. Is this a good way?
For issue 1, I don't know if there is a best practice for it. Can some one share your insigts? Thanks!
Edit:
Sorry that I forgot to mention that the client and server talks through HTTPS. And the password is sent in POST payload.
In this case, the solution to issue 2 (store bcrypted correct password) in the database is okay, right?
What about in issue 1, in this case, the password can be sent in the post payload in plain text?
Use HTTPS.
Password should be in request body, so use POST.
Don't hash the password before sending.
Compare hash stored in the db with hashed received password.
There is no reason to encrypt passwords. It's a bad idea. They should be hashed and preferably salted. In case someone stoles your database, it'll be harder to compromise your users' passwords.
How to securily store passwords.
As I understood, you want to hide/secure even when saving password. So that nobody can see password from request body.
Password should be hashed when saving in database. Even anyone steel your db he won't be able to compare passwords because he will get hashed password.
Usually, we send request body in logs from where we can take body in case of any error occurs for testing. You can stop request body to send in logs file only when you are saving password only.
In this way, only user will know the password. None of the developer can get password. But this can be a problem when user will get unknown error that you will have take care separately.
I am not shure to understand your requirement.
If you want the good practice, so xenteros is right :
Use HTTPS.
Password should be in request body, so use POST.
Don't hash the password before sending.
Compare hash stored in the db with hashed received password.
There is no reason to encrypt passwords. It's a bad idea. They should
be hashed and preferably salted. In case someone stoles your database, it'll be harder to compromise your users' passwords.
If you absolutly want to use HTTP and not HTTPS you can hash your password with javascript. Don't use encryption with javascript. Someone can reuse it to decrypt the password. And in general don't use encryption to store password for security reasons.
fastest MD5 Implementation in JavaScript
you should trully prefer the solution of xenteros
How to pass the different user name instead of displaying the from email name in mail received to the end user java send mail API.
Atleast you can google first for your question. Anyways refer this.
Is there anyway to get an email sent without putting the password into the code ?
There are many email api-s that enables to send an email with entering the username and password.
Example
sendEmail("myemail#gmail.com","mypass","subject","msg body");
Is there any way around the problem with hard-coding the password in code ?
You have three options to send email:
You include your email and password into the code and in this case
the application will send emails from this email address.
You can ask user to enter his credentials for his email and in this
case you'll receive a mail from user's address.
You can form an intent in your application that will fill neccessary
fields and call user's email client to send this.
If you want silent way to send email then you should choose 1 or 2. But more secure way is to use the third approach.
You can ask the user password one time and then store it in your internal storage. It may be necessary to add a way to change the password later if preferred. Deciding from documentation, the internal storage is even secure, while it is also possible to use additional encryption. This is how most of E-mail clients work.
I have a set of contacts in my database. I want my application to build a custom email template for my clients.
My client can set a custom placeholders such as company name, address:
For example:
Dear <<name>>,
This is to inform you that our <<company name>>, located in <<address>> ...
Sincerely,
<<sender>>
After the template is setup I can then use this as a body to my email. Recipients are then fetched from the database.
I am aware of the java.awt.Desktop package which allows me to create a MAIL URI and open it using the user's default email client. The problem is how can I incorporate the mail merge into it? Can you please guide me on existing libraries or solutions to this?
Use the JavaMail library for sending mails. You will find plenty of examples if you search for "JavaMail example", among others: Sending email via Gmail SMTP example. Regarding the placeholders I would simply use the String.replace function.
You will need to control how the variables in the template are setup. I dont think you can parse an arbitrary string and find out if there are variables in it. Hence when a user is adding a variable, make sure that you insert a variable that your program will understand into the email body. Thats a no brainer but thought I'll add it for completeness.
You could save the email body as a velocity template, making sure the variables you added our velocity templating language compliant. Velocity would be easier than string.replace() if there are complicated templates that are being set up. If its a simple one then String.replace() would do.
http://velocity.apache.org/
Next use the java mail library to send it directly from your java program, or launch the default email client of the box using the Desktop class.
EDIT:
If you would like to open outlook then you will need to use Desktop.mail() API. You can pre-populate the to,cc, bcc, subject and body fields in the outlook send email window by constructing an appropriate URI and passing it to Desktop.mail()
mailto:duke#sun.com?SUBJECT=Happy New Year!&BODY=Happy New Year, Duke!
Have a look here for more info:
http://java.sun.com/developer/technicalArticles/J2SE/Desktop/javase6/desktop_api/
For multiple recipients, separating the email addresses with commas should work. If that doesn't, try with a semi colon. Outlook uses semicolon..