This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Generate MD5 hash in Java
Can some one tell me how to convert a string into MD5 format in Java?
I have code like this, but I want in MD5 format with 32 characters.
UUID uuid = UUID.randomUUID();
String token = uuid.toString().substring(0,12);
Implemenation
import java.security.MessageDigest;
import java.math.BigInteger;
import java.lang.String
public class SecurityUtil {
public static String stringToMD5(String string) throws NoSuchAlgorithmException {
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
messageDigest.update(string.getBytes(Charset.forName("UTF-8")),0,string.length());
return new BigInteger(1,messageDigest.digest()).toString(16);
}
}
Usage:
System.out.println(String.format("MD5: %s", stringToMD5("P#$$\\/\\/R|)")));
Output:
MD5: 91162629d258a876ee994e9233b2ad87*
In this sample was used the coding UTF-8.
What is Charset ?
What is MessageDigest ?
What is UTF-8 >
*md5 is example from Wikipedia.
I got bored again...
/**
* #author BjornS
* #created 2. sep. 2010
*/
public enum HashUtil {
SHA1("SHA1"), MD5("MD5"), MD2("MD2"), SHA256("SHA-256"), SHA384("SHA-384"), SHA512("SHA-512");
private final MessageDigest digester;
HashUtil(String algorithm) {
try {
digester = MessageDigest.getInstance(algorithm);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
public String hash(byte[] in) {
return toHexString(digester.digest(in));
}
public String hash(String in) {
return hash(in.getBytes());
}
public String hash(String in, Charset characterSet) {
return hash(in.getBytes(characterSet));
}
public byte[] hashToByteArray(String in) {
return digester.digest(in.getBytes());
}
public byte[] hashToByteArray(String in, Charset characterSet) {
return digester.digest(in.getBytes(characterSet));
}
public byte[] hashToByteArray(byte[] in) {
return digester.digest(in);
}
private String toHexString(byte[] digest) {
StringBuffer hexStr = new StringBuffer(40);
for (byte b : digest) {
hexStr.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1));
}
return hexStr.toString();
}
}
-
/*** ***/
// Use Charsets from Google Guava rather than manually code the charset request, you also don't have to catch exceptions this way! :)
pulic static void main(String... args) {
UUID uuid = UUID.randomUUID();
String uuidString = uuid.toString().substring(0,12);
String token = HashUtil.MD5.hash(uuidString,Charsets.UTF_8);
}
This worked for me..
UUID uuid = UUID.randomUUID();
String token = MD5.digest(uuid.toString().substring(0,12));
thanks for all the answers guys.
Related
In yii2 using generatePasswordHash and validatePassword to verify password like this.
After encrypted it store in DB with password_hash
$2y$13$1hVeVwvuKQUE.kJfaQLje.b8iLlTauTOksddD5Gqn6UC416NsnAR2
auth_key oEx6MM0pGs6jHvApr2anxJEINpTpqGUO
Now how to using java to verify the password?
And what is the auth_key means, as verify don't need to input the auth_key.
All you need is create your custom Class in Java taking and converting from PHP class \yii\base\Security (source is here). Regarding auth key this question already asked here in SO
Finally solved with the following, the tricky part is replace the header.
public class CheckPassword {
public static boolean checkPassword(String passwordText, String DbHash) {
boolean password_verified = false;
if (null != DbHash) {
if (DbHash.startsWith("$2y$")) {
DbHash = "$2a$" + DbHash.substring(4);
}
}
if (null == DbHash || !DbHash.startsWith("$2a$")) {
throw new java.lang.IllegalArgumentException("Invalid hash provided for comparison");
}
password_verified = BCrypt.checkpw(passwordText, DbHash);
return (password_verified);
}
public static void main(String[] args) {
CheckPassword.checkPassword("xxxxx", "$2y$13$5mqgv2wZve89Bz.g1MUcg.7xNich7/nxxxxxxxxxx");
try {
String salt = getSalt();
System.out.println("salt:" + salt);//获取salt
String miwen = getPBKDF2("111", salt); //明文密码加密
System.out.println("miwen:" + miwen);
System.out.println(salt + miwen);
System.out.println(verify("111", salt + miwen));//解密
} catch (Exception e) {
e.printStackTrace();
}
}
public static final String PBKDF2_ALGORITHM = "PBKDF2WithHmacSHA1";
//盐的长度
public static final int SALT_SIZE = 16;
//生成密文的长度
public static final int HASH_SIZE = 16;
// 迭代次数
public static final int PBKDF2_ITERATIONS = 1000;
/**
* 对输入的密码进行验证
* password 密码明文
* dataPassWord 密码加密
*/
public static boolean verify(String password, String dataPassWord)
throws NoSuchAlgorithmException, InvalidKeySpecException {
// 用相同的盐值对用户输入的密码进行加密
String result = getPBKDF2(password, dataPassWord.substring(0, 16));
// 把加密后的密文和原密文进行比较,相同则验证成功,否则失败
return result.equals(dataPassWord.substring(16, dataPassWord.length()));
}
/**
* 根据password和salt生成密文
*/
public static String getPBKDF2(String password, String salt) throws NoSuchAlgorithmException,
InvalidKeySpecException {
//将16进制字符串形式的salt转换成byte数组
byte[] bytes = DatatypeConverter.parseHexBinary(salt);
KeySpec spec = new PBEKeySpec(password.toCharArray(), bytes, PBKDF2_ITERATIONS, HASH_SIZE * 4);
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(PBKDF2_ALGORITHM);
byte[] hash = secretKeyFactory.generateSecret(spec).getEncoded();
//将byte数组转换为16进制的字符串
return DatatypeConverter.printHexBinary(hash);
}
/**
* 生成随机盐值
*/
public static String getSalt() throws NoSuchAlgorithmException {
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
byte[] bytes = new byte[SALT_SIZE / 2];
random.nextBytes(bytes);
//将byte数组转换为16进制的字符串
String salt = DatatypeConverter.printHexBinary(bytes);
return salt;
}
}
I got a .eml file, and some attachments inside
one of attachments - is .rar file
I using Tika to extract this rar, but sometimes Tika cant correctly convert some names of files, for example - such a name
=?koi8-r?Q?6=5F=F4=ED=5F15=2E05=2Erar?=
So i was looking for an answer, how to convert such a string to correctly readed value
Is there any libraries in java, to do this?
I guess it happends cause string got =?koi8-r?Q? in the start, so maybe, if i convert string to something like this, i will get move convertable value, like this 6=5F=F4=ED=5F15=2E05=2E, but if i will do so, i finnaly couldnt find a solution to convert
Does anybody know how to convert such a string correctly?
I spend a lot of time to make it, but still - no results...
Here is a code
public class EncodingUtils {
private EncodingUtils() {
}
public static String decodeKoi8r(String text) {
String decode;
try {
decode = MimeUtility.decodeText(text);
} catch (UnsupportedEncodingException e) {
decode = text;
}
if (isQuotedKoi8r(decode)) {
decode = decode(text, "KOI8-R", "quoted-printable", "KOI8-R");
}
return decode;
}
public static boolean isQuotedKoi8r(String text) {
return text.contains("=") || text.toLowerCase().contains("koi8-r");
}
public static String decode(String text, String textEncoding, String encoding, String resultCharset) {
if (text.length() == 0) {
return text;
}
try {
byte[] bytes = text.getBytes(textEncoding);
InputStream decodedStream = MimeUtility.decode(new ByteArrayInputStream(bytes), encoding);
byte[] tmp = new byte[bytes.length];
int n = decodedStream.read(tmp);
byte[] res = new byte[n];
System.arraycopy(tmp, 0, res, 0, n);
return new String(res, resultCharset);
} catch (IOException | MessagingException e) {
return text;
}
}
}
And test:
public class EncodingUtilsTest {
#Test
public void koi8r() {
String input = "=?koi8-r?Q?11=5F=F4=ED=5F21=2E05=2Erar?=";
String decode = EncodingUtils.decodeKoi8r(input);
Assertions.assertEquals("11_ТМ_21.05.rar", decode);
}
#Test
public void koi8rWithoutStartTag() {
String input = "=CF=D4=C4=C5=CC=D8=CE=D9=CD =D4=D2=C1=CE=DB=C5=CD =D2=C5=DA=C0=CD=.eml";
String decode = EncodingUtils.decodeKoi8r(input);
Assertions.assertEquals("отдельным траншем резюм=.eml", decode);
}
}
Good day!
I keep getting the following error from the code below
error:
AccountController.java:55: error: cannot find symbol
return encoded;
^
symbol: variable encoded
location: class AccountController
1 error
code:
public static String hash(String password) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] byteOfTextToHash = password.getBytes(StandardCharsets.UTF_8);
byte[] hashedByetArray = digest.digest(byteOfTextToHash);
String encoded;
encoded = Base64.getEncoder().encodeToString(hashedByetArray);
} catch(NoSuchAlgorithmException e) {
e.printStackTrace();
};
return encoded;
}
Thanks for the help!
Your encoded variable is out of scope. Move it outside the try will fix this like:
public static String hash(String password) {
String encoded = null;
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] byteOfTextToHash = password.getBytes(StandardCharsets.UTF_8);
byte[] hashedByetArray = digest.digest(byteOfTextToHash);
encoded = Base64.getEncoder().encodeToString(hashedByetArray);
} catch(NoSuchAlgorithmException e) {
e.printStackTrace();
};
return encoded;
}
Declare the varibale encoded outside try and initialize it with null or empty string as below
String encoded = "";
try {
....
}catch(Exception exc):\{
....
}
return encoded
;
I'm given a base64 string (I've no control over what string I'm given):
PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxzYW1scDpSZXNwb25zZSB4bWxuczpzYW1scD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sIg==
When I decode it, in Java, it yields:
<?xml version="1.0"?>
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
When I base64 encode that (again, in Java) it yields:
PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8c2FtbHA6UmVzcG9uc2UgeG1sbnM6c2FtbHA9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpwcm90b2NvbCI=
These strings are different, but they should be the same.
During my search I stumbled upon this site here: https://www.base64encode.org
While on this site, if I click the encode button I get the same results as my java base64 encode.
However, if instead of hitting the encode button, I click on the "Live Mode On" button, I get the original base64-encoded string I received--which is exactly what I want!
Any idea how I can achieve these same results in my own code?
public String getEncodedSAMLMessage(String message) {
byte[] byteMessage;
try {
byteMessage = message.getBytes("UTF-8");
String base64Encoded = helpers.base64Encode(byteMessage);
return URLEncoder.encode(base64Encoded, "UTF-8");
} catch (UnsupportedEncodingException e1) {
}
return null;
}
public String getDecodedSAMLMessage(String message) {
String urlDecoded = helpers.urlDecode(message);
byte[] base64Decoded = helpers.base64Decode(urlDecoded);
try {
return new String(base64Decoded, "UTF-8");
} catch (UnsupportedEncodingException e) {
}
return null;
}
Try using Apache Commons Codec.
import org.apache.commons.codec.Charsets;
import org.apache.commons.codec.binary.Base64;
public class Base64Encoder {
private Base64 b64 = new Base64();
public String encode(String message) {
return b64.encodeAsString(message.getBytes());
}
public String decode(String message) {
return new String(b64.decode(message), Charsets.UTF_8);
}
}
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 7 years ago.
I have the following problem.
I have 2 functions in my code which are intended to encrypt / decrypt simple string.
SO:
I have to pass a string "someString" to the function:
public static String doEncryption(String input) {
try {
if (!RSAService.areKeysPresent()) {
RSAService.generateKey();
}
ObjectInputStream inputStream;
// Encrypt the string using the public key
inputStream = new ObjectInputStream(new FileInputStream(PUBLIC_KEY_FILE));
PublicKey publicKey = (PublicKey) inputStream.readObject();
byte[] cipherText = RSAService.encrypt(input, publicKey);
return cipherText.toString();
} catch (Exception e) {
e.printStackTrace();
}
return "ERROR: Public key file is probably missing";
}
the function doEncryption("someString") returns "[B#61decc8c"
Now I have to embed this string in a url and the server side code should get it from there.
So far it is all good , but when I call the function
public static String doDecryption(String input) {
try {
if (!RSAService.areKeysPresent()) {
RSAService.generateKey();
}
ObjectInputStream inputStream;
// Decrypt the cipher text using the private key.
inputStream = new ObjectInputStream(new FileInputStream(PRIVATE_KEY_FILE));
PrivateKey privateKey = (PrivateKey) inputStream.readObject();
String out = decrypt(input.getBytes(), privateKey);
return out;
} catch (Exception e) {
e.printStackTrace();
}
return "ERROR: Private key file is probably missing or doesn't match the public key";
}
the doDecryption("[B#61decc8c") screams with the following exception:
javax.crypto.BadPaddingException: Data must start with zero
at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:325)
at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:272)
at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:356)
at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:382)
at javax.crypto.Cipher.doFinal(Cipher.java:2087)
at rsaendecryptor.RSAService.decrypt(RSAService.java:132)
at rsaendecryptor.RSAService.doDecryption(RSAService.java:180)
at rsaendecryptor.RSAEnDecrypt.main(RSAEnDecrypt.java:20)
java.lang.NullPointerException
at java.lang.String.<init>(String.java:556)
at rsaendecryptor.RSAService.decrypt(RSAService.java:138)
at rsaendecryptor.RSAService.doDecryption(RSAService.java:180)
at rsaendecryptor.RSAEnDecrypt.main(RSAEnDecrypt.java:20)
Is there any way I can work around this? I have to pass string between the client and the server side because they can be even in different domains. Not to mention that the string will be actually generated from .Net logic and send to Java server side. Encryption to string works fine... What should I do to fix the decryption.
Here is the full class code:
public class RSAService {
/**
* String to hold name of the encryption algorithm.
*/
public static final String ALGORITHM = "RSA";
/**
* String to hold the name of the private key file.
*/
public static final String PRIVATE_KEY_FILE = "private.key";
/**
* String to hold name of the public key file.
*/
public static final String PUBLIC_KEY_FILE = "public.key";
/**
* Generate key which contains a pair of private and public key using 1024
* bytes. Store the set of keys in Prvate.key and Public.key files.
*
*/
public static void generateKey() {
try {
final KeyPairGenerator keyGen = KeyPairGenerator.getInstance(ALGORITHM);
keyGen.initialize(1024);
final KeyPair key = keyGen.generateKeyPair();
File privateKeyFile = new File(PRIVATE_KEY_FILE);
File publicKeyFile = new File(PUBLIC_KEY_FILE);
// Create files to store public and private key
privateKeyFile.createNewFile();
if (publicKeyFile.getParentFile() != null) {
publicKeyFile.getParentFile().mkdirs();
}
publicKeyFile.createNewFile();
// Saving the Public key in a file
ObjectOutputStream publicKeyOS = new ObjectOutputStream(
new FileOutputStream(publicKeyFile));
publicKeyOS.writeObject(key.getPublic());
publicKeyOS.close();
// Saving the Private key in a file
ObjectOutputStream privateKeyOS = new ObjectOutputStream(
new FileOutputStream(privateKeyFile));
privateKeyOS.writeObject(key.getPrivate());
privateKeyOS.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* The method checks if the pair of public and private key has been
* generated.
*
* #return flag indicating if the pair of keys were generated.
*/
public static boolean areKeysPresent() {
File privateKey = new File(PRIVATE_KEY_FILE);
File publicKey = new File(PUBLIC_KEY_FILE);
if (privateKey.exists() && publicKey.exists()) {
return true;
}
return false;
}
/**
* Encrypt the plain text using public key.
*
* #param text : original plain text
* #param key :The public key
* #return Encrypted text
* #throws java.lang.Exception
*/
public static byte[] encrypt(String text, PublicKey key) {
byte[] cipherText = null;
try {
// get an RSA cipher object and print the provider
final Cipher cipher = Cipher.getInstance(ALGORITHM);
// encrypt the plain text using the public key
cipher.init(Cipher.ENCRYPT_MODE, key);
cipherText = cipher.doFinal(text.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
return cipherText;
}
/**
* Decrypt text using private key.
*
* #param text :encrypted text
* #param key :The private key
* #return plain text
* #throws java.lang.Exception
*/
public static String decrypt(byte[] text, PrivateKey key) {
byte[] dectyptedText = null;
try {
// get an RSA cipher object and print the provider
final Cipher cipher = Cipher.getInstance(ALGORITHM);
// decrypt the text using the private key
cipher.init(Cipher.DECRYPT_MODE, key);
dectyptedText = cipher.doFinal(text);
} catch (Exception ex) {
ex.printStackTrace();
}
return new String(dectyptedText);
}
public static String doEncryption(String input) {
try {
if (!RSAService.areKeysPresent()) {
RSAService.generateKey();
}
ObjectInputStream inputStream;
// Encrypt the string using the public key
inputStream = new ObjectInputStream(new FileInputStream(PUBLIC_KEY_FILE));
PublicKey publicKey = (PublicKey) inputStream.readObject();
byte[] cipherText = RSAService.encrypt(input, publicKey);
return cipherText.toString();
} catch (Exception e) {
e.printStackTrace();
}
return "ERROR: Public key file is probably missing";
}
public static String doDecryption(String input) {
try {
if (!RSAService.areKeysPresent()) {
RSAService.generateKey();
}
ObjectInputStream inputStream;
// Decrypt the cipher text using the private key.
inputStream = new ObjectInputStream(new FileInputStream(PRIVATE_KEY_FILE));
PrivateKey privateKey = (PrivateKey) inputStream.readObject();
String out = decrypt(input.getBytes(), privateKey);
return out;
} catch (Exception e) {
e.printStackTrace();
}
return "ERROR: Private key file is probably missing or doesn't match the public key";
}
}
public static String doEncryption(String input)
Stop right there. String is not a container for binary data, and therefore shouldn't have been used to contain the ciphertext in the first place. It should have been passed around as a byte[].
NB when you get an exception, don't guess at what the condition was and return a string that says what it 'probably' was. It makes debugging a guessing came. Use the message that came with the exception.
Thanks to shikjohari and this article here I was able to fix my code!
in the doEncryption() method I modified the return as follows:
return (Base64.encode(cipherText)).toString();
and in doDecryption() method I modified the return as follows:
String out = decrypt(Base64.decode(input), privateKey);
return out;
You can get the full code from my first post and just edit the returns of the two methods as per this post. Hope this helps.