here is the steps,
1. create two jsps. [ login.jsp, validate.jsp ]
2. create one java.
3. Add cryptojs lib [ aes.js ] in your javascript path and mentioned in login.jsp.
here is the sample code.
1. login.jsp
<%@page import="java.util.Arrays"%>
<%@page import="package.Security"%>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%
session.setAttribute ( "RANDKEY", Security.generateSecret ( ) );
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<script src="./js/rollups/aes.js"></script>
<script src="./js/rollups/pbkdf2.js"></script>
<script type="text/javascript">
function convertAndSubmit()
{
var salt = CryptoJS.lib.WordArray.random(128/8);
var iv = CryptoJS.lib.WordArray.random(128/8);
//console.log('salt '+ salt );
//console.log('iv '+ iv );
var key128Bits100Iterations = CryptoJS.PBKDF2( '<%=session.getAttribute ( "RANDKEY" ) %>', salt, { keySize: 128/32, iterations: 100 });
//console.log( 'key128Bits100Iterations '+ key128Bits100Iterations);
var encrypted = CryptoJS.AES.encrypt(document.login.password.value, key128Bits100Iterations, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 });
document.login.salt.value = salt;
document.login.iv.value = iv;
document.login.password.value = encrypted;
document.login.submit();
}
</script>
</head>
<body>
<form action="validate.jsp" method="post" name="login" autocomplete="off">
<p>User Name : <input type="text" name="userName"/></p>
<p>
<input type="text" style="display:none;">
Password : <input type="password" name="password"/>
</p>
<p>
<input type="hidden" name="salt"/>
<input type="hidden" name="iv"/>
<input type="button" value="Login" onclick="javascript:convertAndSubmit()"/>
</p>
</form>
</body>
</html>
Insert title here
2. validate.jsp
<%@page import="java.util.Arrays"%>
<%@page import="package.Security"%>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
</head>
<body>
<%
out.println ("<br/>Encrypted Password : " + request.getParameter("password"));
out.println ("<br/>Salt : " + request.getParameter("salt"));
out.println ("<br/>IV : " + request.getParameter("iv"));
out.println ("<br/>Key : " + session.getAttribute ( "RANDKEY" ) );
out.println ("<br/>Original Password : " + Security.decryptAESEncryptWithSaltAndIV(request.getParameter("password"), session.getAttribute ( "RANDKEY" ).toString ( ), request.getParameter("salt"), request.getParameter("iv") ) );
%>
</body>
</html>
<%
out.println ("
Encrypted Password : " + request.getParameter("password"));
out.println ("
Salt : " + request.getParameter("salt"));
out.println ("
IV : " + request.getParameter("iv"));
out.println ("
Key : " + session.getAttribute ( "RANDKEY" ) );
out.println ("
Original Password : " + YourJava.decryptAESEncryptWithSaltAndIV(request.getParameter("password"), session.getAttribute ( "RANDKEY" ).toString ( ), request.getParameter("salt"), request.getParameter("iv") ) );
%>
3. Security.java [add the below methods ]
/**
* Hex string to byte array.
*
* @param s the s
* @return the byte[]
*/
public static byte [] hexStringToByteArray ( String s )
{
int len = s.length ();
byte [] data = new byte[len / 2];
for ( int i = 0; i < len; i += 2 )
{
data[i / 2] = (byte) ( ( Character.digit ( s.charAt ( i ), 16 ) << 4 ) + Character.digit ( s.charAt ( i + 1 ), 16 ) );
}
return data;
}
/**
* Generate key from password with salt.
*
* @param password the password
* @param saltBytes the salt bytes
* @return the secret key
* @throws GeneralSecurityException the general security exception
*/
public static SecretKey generateKeyFromPasswordWithSalt ( String password, byte [] saltBytes ) throws GeneralSecurityException
{
KeySpec keySpec = new PBEKeySpec ( password.toCharArray (), saltBytes, 100, 128 );
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance ( PBKDF2_WITH_HMAC_SHA1 );
SecretKey secretKey = keyFactory.generateSecret ( keySpec );
return new SecretKeySpec ( secretKey.getEncoded (), AES );
}
/**
* Decrypt aes encrypt with salt and iv.
*
* @param encryptedData the encrypted data
* @param key the key
* @param salt the salt
* @param iv the iv
* @return the string
* @throws Exception the exception
*/
public static String decryptAESEncryptWithSaltAndIV ( String encryptedData, String key, String salt, String iv ) throws Exception
{
byte [] saltBytes = hexStringToByteArray ( salt );
byte [] ivBytes = hexStringToByteArray ( iv );
IvParameterSpec ivParameterSpec = new IvParameterSpec ( ivBytes );
SecretKeySpec sKey = (SecretKeySpec) generateKeyFromPasswordWithSalt ( key, saltBytes );
Cipher c = Cipher.getInstance ( AES_CBC_PKCS5_PADDING );
c.init ( Cipher.DECRYPT_MODE, sKey, ivParameterSpec );
byte [] decordedValue = new BASE64Decoder ().decodeBuffer ( encryptedData );
byte [] decValue = c.doFinal ( decordedValue );
String decryptedValue = new String ( decValue );
return decryptedValue;
}
public String generateSecret ( )
{
return "1234455553dsfdfdsfdsf"; //generate always random number and send for each request
}
// enjoy madi.
1. create two jsps. [ login.jsp, validate.jsp ]
2. create one java.
3. Add cryptojs lib [ aes.js ] in your javascript path and mentioned in login.jsp.
here is the sample code.
1. login.jsp
<%@page import="java.util.Arrays"%>
<%@page import="package.Security"%>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%
session.setAttribute ( "RANDKEY", Security.generateSecret ( ) );
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<script src="./js/rollups/aes.js"></script>
<script src="./js/rollups/pbkdf2.js"></script>
<script type="text/javascript">
function convertAndSubmit()
{
var salt = CryptoJS.lib.WordArray.random(128/8);
var iv = CryptoJS.lib.WordArray.random(128/8);
//console.log('salt '+ salt );
//console.log('iv '+ iv );
var key128Bits100Iterations = CryptoJS.PBKDF2( '<%=session.getAttribute ( "RANDKEY" ) %>', salt, { keySize: 128/32, iterations: 100 });
//console.log( 'key128Bits100Iterations '+ key128Bits100Iterations);
var encrypted = CryptoJS.AES.encrypt(document.login.password.value, key128Bits100Iterations, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 });
document.login.salt.value = salt;
document.login.iv.value = iv;
document.login.password.value = encrypted;
document.login.submit();
}
</script>
</head>
<body>
<form action="validate.jsp" method="post" name="login" autocomplete="off">
<p>User Name : <input type="text" name="userName"/></p>
<p>
<input type="text" style="display:none;">
Password : <input type="password" name="password"/>
</p>
<p>
<input type="hidden" name="salt"/>
<input type="hidden" name="iv"/>
<input type="button" value="Login" onclick="javascript:convertAndSubmit()"/>
</p>
</form>
</body>
</html>
2. validate.jsp
<%@page import="java.util.Arrays"%>
<%@page import="package.Security"%>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
</head>
<body>
<%
out.println ("<br/>Encrypted Password : " + request.getParameter("password"));
out.println ("<br/>Salt : " + request.getParameter("salt"));
out.println ("<br/>IV : " + request.getParameter("iv"));
out.println ("<br/>Key : " + session.getAttribute ( "RANDKEY" ) );
out.println ("<br/>Original Password : " + Security.decryptAESEncryptWithSaltAndIV(request.getParameter("password"), session.getAttribute ( "RANDKEY" ).toString ( ), request.getParameter("salt"), request.getParameter("iv") ) );
%>
</body>
</html>
<%
out.println ("
Encrypted Password : " + request.getParameter("password"));
out.println ("
Salt : " + request.getParameter("salt"));
out.println ("
IV : " + request.getParameter("iv"));
out.println ("
Key : " + session.getAttribute ( "RANDKEY" ) );
out.println ("
Original Password : " + YourJava.decryptAESEncryptWithSaltAndIV(request.getParameter("password"), session.getAttribute ( "RANDKEY" ).toString ( ), request.getParameter("salt"), request.getParameter("iv") ) );
%>
3. Security.java [add the below methods ]
/**
* Hex string to byte array.
*
* @param s the s
* @return the byte[]
*/
public static byte [] hexStringToByteArray ( String s )
{
int len = s.length ();
byte [] data = new byte[len / 2];
for ( int i = 0; i < len; i += 2 )
{
data[i / 2] = (byte) ( ( Character.digit ( s.charAt ( i ), 16 ) << 4 ) + Character.digit ( s.charAt ( i + 1 ), 16 ) );
}
return data;
}
/**
* Generate key from password with salt.
*
* @param password the password
* @param saltBytes the salt bytes
* @return the secret key
* @throws GeneralSecurityException the general security exception
*/
public static SecretKey generateKeyFromPasswordWithSalt ( String password, byte [] saltBytes ) throws GeneralSecurityException
{
KeySpec keySpec = new PBEKeySpec ( password.toCharArray (), saltBytes, 100, 128 );
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance ( PBKDF2_WITH_HMAC_SHA1 );
SecretKey secretKey = keyFactory.generateSecret ( keySpec );
return new SecretKeySpec ( secretKey.getEncoded (), AES );
}
/**
* Decrypt aes encrypt with salt and iv.
*
* @param encryptedData the encrypted data
* @param key the key
* @param salt the salt
* @param iv the iv
* @return the string
* @throws Exception the exception
*/
public static String decryptAESEncryptWithSaltAndIV ( String encryptedData, String key, String salt, String iv ) throws Exception
{
byte [] saltBytes = hexStringToByteArray ( salt );
byte [] ivBytes = hexStringToByteArray ( iv );
IvParameterSpec ivParameterSpec = new IvParameterSpec ( ivBytes );
SecretKeySpec sKey = (SecretKeySpec) generateKeyFromPasswordWithSalt ( key, saltBytes );
Cipher c = Cipher.getInstance ( AES_CBC_PKCS5_PADDING );
c.init ( Cipher.DECRYPT_MODE, sKey, ivParameterSpec );
byte [] decordedValue = new BASE64Decoder ().decodeBuffer ( encryptedData );
byte [] decValue = c.doFinal ( decordedValue );
String decryptedValue = new String ( decValue );
return decryptedValue;
}
public String generateSecret ( )
{
return "1234455553dsfdfdsfdsf"; //generate always random number and send for each request
}
// enjoy madi.
6 comments:
Hello Vijay,
Please help,
Where can i get the com.gnax.sdex.soa.distributable.common.SdexSecurity .
Also the link for the js files if you can share.
Regards
Pramod.
yourjava.java
is that file SdexSecurity. you can name it by your choice and change the package name where com.gnax.sdex.soa.distributable.common.SdexSecurity
hope it will helps.
#Pramod Kumar
See, I changed as security.java for your easy ref..
Hi Vijay,
I copied all your code and I ran it getting a java exception: " (javax.crypto.BadPaddingException) javax.crypto.BadPaddingException: Given final block not properly padded" in the doFinal method call. Any suggestions?
Regards
Fernando Iglesias
# Fernando Iglesias - Please create this as small java project and send to me, i will fix that and attach u back.
drvijayy2k2@gmail.com
Hey Vijay I am getting same error.. javax.crypto.BadPaddingException:
I think its because Crypto Js do Pkcs7 padding and Java supports till padding 5. Please help me out.
Post a Comment