Dear Reader,
When you need an application where some Password is required to start the application and that need
to be entered in Console (Unix OS/Windows OS) manually Eg: Starting Master HSM server for Card Encryption/Decryption,
Starting Unix based critical applications, you don't want to show either * or text while typing password. This may
cause a shoulder surfing.
In Java you can do this using Below API, I have tested this Windows and UNIX. Running this in Eclipse will throw Exception.
Hence Run in Command Prompt.
import java.io.Console;
public class HSMPassword {
public static void main(String[] args) {
char[] pass ;
Console console = System.console();
System.out.println("Reading Password From Console, Please Press Enter after typing your password.");
pass = console.readPassword("");
String slotPIN = new String(pass);
System.out.println("Password Entered is: "+slotPIN);
}
}
--------------Starting in Console--------------------
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
E:\MyDiary>javac HSMPassword.java
E:\MyDiary>java HSMPassword
Reading Password From Console, Please Press Enter after typing your password.
Password Entered is: deepak
E:\MyDiary>java HSMPassword
Reading Password From Console, Please Press Enter after typing your password.
Password Entered is: hello
E:\MyDiary>
Showing posts with label Java Security. Show all posts
Showing posts with label Java Security. Show all posts
Friday, May 5, 2017
Sensitive Password Entry in Console using Java
Wednesday, January 11, 2017
Chrome issue : ERR_SSL_VERSION_OR_CIPHER_MISMATCH
Chrome issue: ERR_SSL_VERSION_OR_CIPHER_MISMATCH
If you get this error while hitting an URL in chrome, it means the recently Updated Chrome version doesn't support SSLv3 protocol.
So if you Use an older version of Chrome or Firefox, you won't get this error. This is Browser's error which occurs only when
there is some problem at client side while establishing private connection to a secure site and this error is related to “SSL Certificate” security.
Solution:
Temporary at client side:
1) Use older version of Chrome or Mozilla, remove recently updated version.
2) Open "chrome://flags" in Chrome URL and search for SSL, then change the drop down option to support SSLv3.
Permanently:
1) Since your application is running in an Application Server (Web Server). Make the "sslProtocols" change and CIPHERs change.
The below change is for JBOSS server (open JBOSS/server/YOUR_MODULE/deploy/jboss-web-deployer/server.xml) and modify below changes as:
<Connector port="6443" address="${jboss.bind.address}" SSLEnabled="true"
maxThreads="250" maxHttpHeaderSize="8192"
emptySessionPath="false" protocol="HTTP/1.1" scheme="https" secure="true"
enableLookups="false" acceptCount="100"
connectionTimeout="20000" disableUploadTimeout="true" server=" "
clientAuth="false" keystoreFile="${jboss.server.home.dir}/conf/servercerts" keystorePass="*******"
sslProtocols="TLSv1,TLSv1.1,TLSv1.2" ciphers="TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
TLS_RSA_WITH_AES_128_CBC_SHA256,
TLS_RSA_WITH_AES_128_CBC_SHA,
TLS_RSA_WITH_AES_256_CBC_SHA256,
TLS_RSA_WITH_AES_256_CBC_SHA,
SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA" />
Save the file and restart the Application Server. Issue will be resolved.
Thursday, March 15, 2012
Implementation of Java Cryptography Extension
Implementation of Java Cryptography Extension (JCE) in Programs
Dear friend,
JCE is a huge topic in Java programming language. There are many books written on the same.
I am writing a basic example to show how it works, for complete details and loop holes please
google it:
I will show: how do use JCE to encrypt or decrypt a text in Data Encryption Standard (DES) mechanism.
Steps to do:
1) Generate the key.
2) Create the Cipher.
3) Initialize the Cipher for Encryption using key.
4) Encrypt the text.
5) Again initialize the Cipher for Decryption using the same key.
6) Decrypt the text.
//CryptoMain.java
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
public class CryptoMain {
public static void main(String[] argv) {
try {
//Generate the Key
KeyGenerator keygenerator = KeyGenerator.getInstance("DES");
SecretKey myDesKey = keygenerator.generateKey();
//Create the cipher
Cipher desCipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
// Initialize the cipher for encryption
desCipher.init(Cipher.ENCRYPT_MODE, myDesKey);
//sensitive information
byte[] text = "Password_Content".getBytes();
System.out.println("Text [Byte Format] : " + text);
System.out.println("Text : " + new String(text));
//Encrypt the text
byte[] textEncrypted = desCipher.doFinal(text);
System.out.println("Text Encrypted : " + textEncrypted);
//Initialize the same cipher for decryption, using the same key
desCipher.init(Cipher.DECRYPT_MODE, myDesKey);
//Decrypt the text
byte[] textDecrypted = desCipher.doFinal(textEncrypted);
System.out.println("Text Decrypted : " + new String(textDecrypted));
}
catch(NoSuchAlgorithmException e){
e.printStackTrace();
}
catch(NoSuchPaddingException e){
e.printStackTrace();
}
catch(InvalidKeyException e){
e.printStackTrace();
}
catch(IllegalBlockSizeException e){
e.printStackTrace();
}
catch(BadPaddingException e){
e.printStackTrace();
}
}
}
//Output:
Text [Byte Format] : [B@1f585b
Text : Password_Content
Text Encrypted : [B@1f593c
Text Decrypted : Password_Content
Details about creation of cipher: Create a Cipher instance from Cipher class, specify the following
information and separated by a slashes (/).
a. Algorithm name
b. Mode (optional)
c. Padding scheme (optional)
Cipher desCipher;
// Create the cipher
desCipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
Note :
DES = Data Encryption Standard.
ECB = Electronic Codebook mode.
PKCS5Padding = PKCS #5-style padding.
In this case, you created a DES (Data Encryption Standard) cipher in Electronic Codebook mode, with
PKCS #5-style padding.
---------------------END----------------------
Thursday, December 1, 2011
Generating Secure Numbers or Random Numbers like PIN/OTP
Dear Reader,
I am writing a useful post here: How to generate Secure Number sequences or Random Number sequences like PIN/One time
passwords or any number sequence for Temporary passwords which are numeric. I have explained the complete tutorial by
giving first a practical example that we use in our coding practices. The complete theory is given at the below section
after coding example.
At first, I have written code to generate simple Random Number based on given length, then the secure one:
While generating random numbers in Java for Security purposes, we use java.security.SecureRandom class or
org.apache.commons.lang.RandomStringUtils class. SecureRandom class is designed to provide cryptographically secure
random numbers, however sometime it's become quite predictable if not used properly. I explained below:
SecureRandom class uses Pseudo Random Number Generator (PRNG) implementation for generating numbers. The PRNGs are
part of Cryptographic Service Providers (CSP) (here SUN for JAVA) is default CSP. On Windows env, SUN CSP uses "SHA1PRNG"
algorithm. On Unix env it is using something else, not mentioning here. At present, we use this Window's environment only.
SecureRandom sr1 = new SecureRandom();
//The following will create SUN SHA1PRNG if the highest priority CSP is SUN
SecureRandom sr2 = SecureRandom.getInstance("SHA1PRNG");
//The following will always create SUN SHA1PRNG
SecureRandom sr3 = SecureRandom.getInstance("SHA1PRNG", "SUN");
The PRNG tries to ensure that the output does not reveal any information about the seed, and that somebody observing the
output cannot predict future outputs without knowing the seed.
What is SEED?
An early computer-based PRNG, suggested by John von Neumann in 1946, is known as the middle-square method. The algorithm
is as follows: take any number, square it, remove the middle digits of the resulting number as the "random number", then
use that number as the seed for the next iteration.
For example, squaring the number "1111" yields "1234321", which can be written as "01234321", an 8-digit number being the
square of a 4-digit number. This gives "2343" as the "random" number. Repeating this procedure gives "4896" as the next
result, and so on. "Von Neumann" used 10 digit numbers, but the process was the same.
A problem with this "middle square" method is that all sequences eventually repeat themselves, some very quickly, such
as "0000". Von Neumann was aware of this, but he found the approach sufficient for his purposes, and was worried that
mathematical "fixes" would simply hide errors rather than remove them.
Note that according to Sun’s documentation, the returned java.security.SecureRandom instance is not seeded by any of these
calls. If after one of these calls, java.security.SecureRandom.nextBytes(byte[]) is called, then the PRNG is seeded using a
secure mechanism provided by the underlying operating system (starting with JRE 1.4.1 in Windows and JRE 1.4.2 in Linux and Solaris).
If java.security.SecureRandom.setSeed(long) or java.security.SecureRandom.setSeed(byte[]) is called before a call to
java.security.SecureRandom.nextBytes(byte[]), then the internal seeding mechanism is bypassed, and only the provided seed is used
to generate random numbers.
By bypassing the internal secure seeding mechanism of the SHA1PRNG, you may compromise the security of your PRNG output. If you
seed it with anything that an attacker can potentially predict (e.g. the time when the PRNG instance was created), then using
java.security.SecureRandom may not provide the level of security that you need.
Finally, regardless of how well the PRNG is seeded, it should not be used indefinitely without reseeding. There are two approaches
that can be used for longer-term security of PRNG output:
Periodically throw away the existing java.security.SecureRandom instance and create a new one. This will generate a new instance
with a new seed.
Periodically add new random material to the PRNG seed by making a call to
::::>>> java.security.SecureRandom.setSeed( java.security.SecureRandom.generateSeed(int) ).
In summary, keep the following in mind when using java.security.SecureRandom: Always specify the exact PRNG and provider that you
wish to use. If you just use the default PRNG, you may end up with different PRNGs on different installations of your application that
may need to be called differently in order to work properly. Using the following code to get a PRNG instance is appropriate:
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "SUN");
When using the SHA1PRNG, always call java.security.SecureRandom.nextBytes(byte[]) immediately after creating a new instance of the PRNG.
This will force the PRNG to seed itself securely. If for testing purposes, you need predictable output, ignoring this rule and seeding
the PRNG with hard-coded/predictable values may be appropriate. Use at least JRE 1.4.1 on Windows and at least JRE 1.4.2 on Solaris and Linux.
Earlier versions do not seed the SHA1PRNG securely. Periodically reseed your PRNG as observing a large amount of PRNG output generated
using one seed may allow the attacker to determine the seed and thus predict all future outputs.
Some of the theoretical contents are taken from few websites but are tuned as per my way of writing, however the coding example is
completely mine. Please read and leave the comment if found useful.
Another Example with Seeding:
I am writing a useful post here: How to generate Secure Number sequences or Random Number sequences like PIN/One time
passwords or any number sequence for Temporary passwords which are numeric. I have explained the complete tutorial by
giving first a practical example that we use in our coding practices. The complete theory is given at the below section
after coding example.
At first, I have written code to generate simple Random Number based on given length, then the secure one:
//Basic Random Generator
package com.dmodi.utils;
import org.apache.commons.lang.RandomStringUtils;
//Add commons-lang-2.4.jar
public class RandomNumberGenerator {
public static void main(String[] args) {
for(int i=0;i<10;i++){
System.out.println(generateRandomNumber(6));
System.out.println(generateRandomNumber(12));
}
}
public static String generateRandomNumber(int length){
String randomNumber="";
randomNumber = RandomStringUtils.randomNumeric(length);
return randomNumber;
}
}
===========================================
//Secure Random Generator
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
//Add commons-lang-2.4.jar
import org.apache.commons.lang.RandomStringUtils;
public class OTP_Generation {
public static void main(String[] args) {
int otpLength=4;
for(int i=0; i<10;i++) {
System.out.println("OTP using SecureRandomGenerator: "+(i+1)+"==>"+generateOTP(otpLength));
}
System.out.println("==========================");
for(int i=0; i<10;i++) {
System.out.println("OTP using RandomNumberGenerator: "+(i+1)+"==>"+generateRandomOTP(otpLength));
}
}
public static String generateOTP(int otpLengthNumber){
String otp = new String();
int otpSample=0;
for(int i=0;i<otpLengthNumber;i++){
otp=otp+"9";
}
otpSample=Integer.parseInt(otp);
SecureRandom prng;
try {
prng = SecureRandom.getInstance("SHA1PRNG"); //Number Generation Algorithm
otp = new Integer(prng.nextInt(otpSample)).toString();
otp = (otp.length() < otpLengthNumber) ? padleft(otp, otpLengthNumber, '0') : otp;
} catch (NoSuchAlgorithmException e) {
}
// If generated OTP exists in DB -regenerate OTP again
boolean otpExists=false;
if (otpExists) {
generateOTP(otpLengthNumber);
} else {
return otp;
}
return otp;
}
private static String padleft(String s, int len, char c) { //Fill with some char or put some logic to make more secure
s = s.trim();
StringBuffer d = new StringBuffer(len);
int fill = len - s.length();
while (fill-- > 0)
d.append(c);
d.append(s);
return d.toString();
}
public static String generateRandomOTP(int otpLengthNumber){
String otp = RandomStringUtils.randomNumeric(otpLengthNumber);
return otp;
}
}
While generating random numbers in Java for Security purposes, we use java.security.SecureRandom class or
org.apache.commons.lang.RandomStringUtils class. SecureRandom class is designed to provide cryptographically secure
random numbers, however sometime it's become quite predictable if not used properly. I explained below:
SecureRandom class uses Pseudo Random Number Generator (PRNG) implementation for generating numbers. The PRNGs are
part of Cryptographic Service Providers (CSP) (here SUN for JAVA) is default CSP. On Windows env, SUN CSP uses "SHA1PRNG"
algorithm. On Unix env it is using something else, not mentioning here. At present, we use this Window's environment only.
SecureRandom sr1 = new SecureRandom();
//The following will create SUN SHA1PRNG if the highest priority CSP is SUN
SecureRandom sr2 = SecureRandom.getInstance("SHA1PRNG");
//The following will always create SUN SHA1PRNG
SecureRandom sr3 = SecureRandom.getInstance("SHA1PRNG", "SUN");
The PRNG tries to ensure that the output does not reveal any information about the seed, and that somebody observing the
output cannot predict future outputs without knowing the seed.
What is SEED?
An early computer-based PRNG, suggested by John von Neumann in 1946, is known as the middle-square method. The algorithm
is as follows: take any number, square it, remove the middle digits of the resulting number as the "random number", then
use that number as the seed for the next iteration.
For example, squaring the number "1111" yields "1234321", which can be written as "01234321", an 8-digit number being the
square of a 4-digit number. This gives "2343" as the "random" number. Repeating this procedure gives "4896" as the next
result, and so on. "Von Neumann" used 10 digit numbers, but the process was the same.
A problem with this "middle square" method is that all sequences eventually repeat themselves, some very quickly, such
as "0000". Von Neumann was aware of this, but he found the approach sufficient for his purposes, and was worried that
mathematical "fixes" would simply hide errors rather than remove them.
Note that according to Sun’s documentation, the returned java.security.SecureRandom instance is not seeded by any of these
calls. If after one of these calls, java.security.SecureRandom.nextBytes(byte[]) is called, then the PRNG is seeded using a
secure mechanism provided by the underlying operating system (starting with JRE 1.4.1 in Windows and JRE 1.4.2 in Linux and Solaris).
If java.security.SecureRandom.setSeed(long) or java.security.SecureRandom.setSeed(byte[]) is called before a call to
java.security.SecureRandom.nextBytes(byte[]), then the internal seeding mechanism is bypassed, and only the provided seed is used
to generate random numbers.
By bypassing the internal secure seeding mechanism of the SHA1PRNG, you may compromise the security of your PRNG output. If you
seed it with anything that an attacker can potentially predict (e.g. the time when the PRNG instance was created), then using
java.security.SecureRandom may not provide the level of security that you need.
Finally, regardless of how well the PRNG is seeded, it should not be used indefinitely without reseeding. There are two approaches
that can be used for longer-term security of PRNG output:
Periodically throw away the existing java.security.SecureRandom instance and create a new one. This will generate a new instance
with a new seed.
Periodically add new random material to the PRNG seed by making a call to
::::>>> java.security.SecureRandom.setSeed( java.security.SecureRandom.generateSeed(int) ).
In summary, keep the following in mind when using java.security.SecureRandom: Always specify the exact PRNG and provider that you
wish to use. If you just use the default PRNG, you may end up with different PRNGs on different installations of your application that
may need to be called differently in order to work properly. Using the following code to get a PRNG instance is appropriate:
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "SUN");
When using the SHA1PRNG, always call java.security.SecureRandom.nextBytes(byte[]) immediately after creating a new instance of the PRNG.
This will force the PRNG to seed itself securely. If for testing purposes, you need predictable output, ignoring this rule and seeding
the PRNG with hard-coded/predictable values may be appropriate. Use at least JRE 1.4.1 on Windows and at least JRE 1.4.2 on Solaris and Linux.
Earlier versions do not seed the SHA1PRNG securely. Periodically reseed your PRNG as observing a large amount of PRNG output generated
using one seed may allow the attacker to determine the seed and thus predict all future outputs.
Some of the theoretical contents are taken from few websites but are tuned as per my way of writing, however the coding example is
completely mine. Please read and leave the comment if found useful.
Another Example with Seeding:
try {
// Create a secure random number generator
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
// Get 1024 random bits
byte[] bytes = new byte[1024/8];
sr.nextBytes(bytes);
// Create two secure number generators with the same seed
int seedByteCount = 10;
byte[] seed = sr.generateSeed(seedByteCount);
sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(seed);
}
catch (NoSuchAlgorithmException e) {
}
==========================END==========================
Thursday, June 30, 2011
Security concepts while developing web applications in Java
Few Security concepts while developing web applications in Java
1) Difference between Hashing and Encryption:
Hashing takes any amount of data (binary or text) and creates a constant-length hash representing
a checksum for the data. For example, the hash might be 16 bytes. Different hashing algorithms produce
different size hashes. You obviously cannot re-create the original data from the hash, but you can
hash the Original data again to see if the same hash value is generated.
Ex: Unix-based passwords work this way. The password is stored as a hash value, and to log onto a system,
the password you type is hashed, and the hash value is compared against the hash of the real password.
If they match, then you must've typed the correct password.
Encryption: Encryption means you are encrypting the Original Data into some un-readable format
using some Key or Algorithms and store it or send through Network. Again you can decrypt the same
un-readable data using same Key or Algorithm and generates Original Data.
2) Points to be taken while writing Dynamic Queries in application to prevent Hacking:
a) SQL injection example one:
SELECT * FROM admin_auth_user WHERE Firstname='Obopay' AND FamilyName='Admin';
//8 records returned
SELECT * FROM admin_auth_user WHERE Firstname='Obopay' AND FamilyName='Admin' OR '1'=1;
//ALL 26 records returned, adding the OR clause makes WHERE clause condition always TRUE, so this query becomes:
SELECT * FROM admin_auth_user;
b) SQL injection example two:
//Your application query:
SELECT * FROM items WHERE owner = '" +hackerName+ "' AND itemname = '" +name+"'";
//Query is modified by Hackers using some script in URL and added something like below,
//This will delete all records from table on those DB which supports Batch Execution, eg: SQL server-2000,
//Oracle doesn't support this.
SELECT * FROM items WHERE owner = '" +hackerName+ "' AND itemname = '" +name+ "';DELETE FROM items;SELECT * FROM
items WHERE 'a'='a'";
#######################################
A safe version of the above SQL statement could be coded in Java as:
String firstname = req.getParameter("firstname");
String lastname = req.getParameter("lastname");
//FIXME: Do your own validation to detect attacks
String query = "SELECT id, firstname, lastname FROM authors WHERE forename = ? and surname = ?";
PreparedStatement pstmt = connection.prepareStatement( query );
pstmt.setString( 1, firstname );
pstmt.setString( 2, lastname );
try {
ResultSet results = pstmt.execute( );
}
catch(Exception e){}
########################################
c) Visible Content
Having a simple page, which displays article with given ID as the parameter, the attacker may
perform a couple of simple tests if a page is vulnerable to SQL Injection attack.
Example URL:
http://newspaper.com/items.php?id=2
Sends the following query to the database:
SELECT title, description, body FROM items WHERE ID = 2; //Assume: Returns 1 record
The attacker may try to inject any (even invalid) query, that may cause the query to return no results:
http://newspaper.com/items.php?id=2 and 1=2
Now the SQL query should looks like this:
SELECT title, description, body FROM items WHERE ID = 2 and 1=2; //No records will return as 1=2 is False.
Which means that the query is not going to return anything. Use Again PreparedStatements to fetch only Id.
3) Writing and Inserting Java Script to steal SessionId for a user and use it:
It is easy to steal SessionId cookies with javascript functions planted in trusted sites by
other users. Here we are discussing the possible counter-measures for this kind of attack.
How Hackers do this:
<script>document.cookie</script>
Help is taken from this site (Open Web Application Security Project):
https://www.owasp.org/index.php/HttpOnly
---------------------END---------------------
Subscribe to:
Posts (Atom)