Im trying to call "/api/v1/sub-accounts" endpoint to get Account balance but there is something wrong with it!
here is my code :
public Observable<Response<String>> getBalance(){
long timestamp = Timestamp.from(Instant.now()).getTime() + localDelayTime;
return service.getBalance(
apiKey+"",
timestamp+"",
base64(encode(secKey,(timestamp+"GET"+"/api/v1/sub-accounts"+"")))+"",
base64(encode(secKey,passPhrase))+"",
"2")
.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.retry(2)
.timeout(10,TimeUnit.SECONDS);
}
and my encryption methods are :
private String base64(String encode) {
try {
return Base64.getEncoder().encodeToString((encode).getBytes(StandardCharsets.UTF_8));
}catch (NullPointerException e){
return "";
}
}
and
public static String encode(String key, String data) {
Mac sha256;
try {
sha256 = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
sha256.init(secret_key);
return bytesToHex(sha256.doFinal(data.getBytes("UTF-8")));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String bytesToHex(byte[] bytes) {
char[] HEX_ARRAY = "0123456789abcdef".toCharArray();
char[] hexChars = new char[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = HEX_ARRAY[v >>> 4];
hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
}
return new String(hexChars);
}
the values of 'apikey , secretKey , passPhrase' are right
also the value of timestamp , i checked it with server
This caught me offguard too.
Passphrase is the password to your account not the trading 6 digit code you use.
Related
I'm trying to hash data "text" to be transferred from Java Service to C# Service.
I'm using SHA256 as a Hashing algorithm, but despite the values and the salt being the same the result doesn't.
Here is my C# snippet
public string Sign(string textToHash, string salt){
byte[] convertedHash = new byte[salt.Length / 2];
for (int i = 0; i < salt.Length / 2; i++)
convertedHash[i] = (byte)int.Parse(salt.Substring(i * 2, 2), NumberStyles.HexNumber);
HMAC hasher = new HMACSHA256(convertedHash);
string hexHash = "";
using (hasher)
{
byte[] hashValue = hasher.ComputeHash(Encoding.UTF8.GetBytes(textToHash));
foreach (byte b in hashValue)
{
hexHash += b.ToString("X2");
}
}
return hexHash;
}
And, here is the Java snippet
public static String sign(String textToHash, String salt){
byte[] convertedHash = new byte[salt.length() / 2];
for (int i = 0; i < salt.length() / 2; i++)
{
convertedHash[i] = (byte)Integer.parseInt(salt.substring(i * 2, i * 2 + 2),16);
}
String hashedText = null;
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(convertedHash);
byte[] bytes = md.digest(textToHash.getBytes(StandardCharsets.UTF_8));
StringBuilder sb = new StringBuilder();
for (byte aByte : bytes) {
sb.append(Integer.toString((aByte & 0xff) + 0x100, 16).substring(1));
}
hashedText = sb.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return hashedText;
}
In Java, I also tried
convertedHash = salt.getBytes();
But I got different results also.
Tests:
salt = ABCDEFG
text = hashme
Result in C#
70B38047C28FFEDCF7275C428E65310671CADB65F11A5C9A8CFBB3CF52112BA3
Result in Java
a8bc36606aade01591a1d12c8b3c87aca1fe55def79740def03a90b49f2c6b7c
So, any help about why the results aren't the same.
Thanks in advance.
To mimic the Java hashing, I used SHA256Managed rather than HMACSHA256 in C#
public static string Sign(string data, string salt)
{
UTF8Encoding encoder = new UTF8Encoding();
SHA256Managed sha256hasher = new SHA256Managed();
byte[] convertedHash = new byte[salt.Length / 2];
for (int i = 0; i < salt.Length / 2; i++)
convertedHash[i] = (byte)int.Parse(salt.Substring(i * 2, 2), NumberStyles.HexNumber);
byte[] dataBytes = encoder.GetBytes(data);
byte[] bytes = new byte[convertedHash.Length + dataBytes.Length];
Array.Copy(convertedHash, bytes, convertedHash.Length);
Array.Copy(dataBytes, 0, bytes, convertedHash.Length, dataBytes.Length);
byte[] hashedBytes = sha256hasher.ComputeHash(bytes);
return hashedBytes.Aggregate("", (current, t) => current + t.ToString("X2"));
}
HMACSHA256 is not a pure SHA-256.
I have a class converting string to hexString according to the value named for md5,sha1 sha 256.
How can I convert hexString to String according to these security algoritm.
MD5 Hash: 06c219e5bc8378f3a8a3f83b4b7e4649
SHA-1 Hash: e9fe51f94eadabf54dbf2fbbd57188b9abee436e
SHA-256 Hash: 652c7dc687d98c9889304ed2e408c74b611e86a40caa51c4b43f1dd5913c5cd0
Actual String : mysecret
Here is my code snippet shown below.
public class HashGenerator {
private HashGenerator() {
}
public static String generateMD5(String message) throws HashGenerationException {
return hashString(message, "MD5");
}
public static String generateSHA1(String message) throws HashGenerationException {
return hashString(message, "SHA-1");
}
public static String generateSHA256(String message) throws HashGenerationException {
return hashString(message, "SHA-256");
}
public static String convertFromMD5(String message) throws HashGenerationException{
return hexStringtoByteArray(message, "MD5");
}
public static String convertFromSHA1(String message) throws HashGenerationException{
return hexStringtoByteArray(message, "SHA-1");
}
public static String convertFromSHA256(String message) throws HashGenerationException{
return hexStringtoByteArray(message, "SHA-256");
}
private static String hashString(String message, String algorithm)
throws HashGenerationException {
try {
MessageDigest digest = MessageDigest.getInstance(algorithm);
byte[] hashedBytes = digest.digest(message.getBytes("UTF-8"));
return convertByteArrayToHexString(hashedBytes);
} catch (NoSuchAlgorithmException | UnsupportedEncodingException ex) {
throw new HashGenerationException(
"Could not generate hash from String", ex);
}
}
private static String convertByteArrayToHexString(byte[] arrayBytes) {
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < arrayBytes.length; i++) {
stringBuffer.append(Integer.toString((arrayBytes[i] & 0xff) + 0x100, 16)
.substring(1));
}
return stringBuffer.toString();
}
public static String hexStringtoByteArray(String str, String algorithm)
{
byte[] bytes = new byte[str.length() / 2];
for (int i = 0; i < bytes.length; i++)
{
bytes[i] = (byte) Integer
.parseInt(str.substring(2 * i, 2 * i + 2), 16);
}
try {
MessageDigest digest = MessageDigest.getInstance(algorithm);
byte[] hashedBytes = digest.digest(bytes);
return new String(hashedBytes);
} catch (Exception ex) {
throw new HashGenerationException(
"Could not generate hash from String", ex);
}
}
}
Once you have a byte array from your hex string using hexStringtoByteArray, you can make a string using new String(bytes, "UTF-8") where bytes is the byte array from your method. By specifying UTF-8 when creating the string you get characters other than hex.
Therefore the new method would be as follows:
public String hexStringtoByteArray(String str) {
byte[] bytes = new byte[str.length() / 2];
for (int i = 0; i < bytes.length; i++) {
bytes[i] = (byte) Integer.parseInt(str.substring(2 * i, 2 * i + 2), 16);
}
return new String(bytes, "UTF-8");
}
In PHP Without pack function
$message = "hello world";
$key = "7E066";
echo hash_hmac('SHA256',$message, $key);
I get 0315a69471ebe855e9e221a374b30d8de08dcc833857f964737632698c87278e
In Java
String data = "hello world";
String key = "7E066";
System.out.println(hmacSha(key,data, "HmacSHA256"));
private static String hmacSha(String KEY, String VALUE, String SHA_TYPE) {
try {
SecretKeySpec signingKey = new SecretKeySpec(KEY.getBytes("UTF-8"), SHA_TYPE);
Mac mac = Mac.getInstance(SHA_TYPE);
mac.init(signingKey);
byte[] rawHmac = mac.doFinal(VALUE.getBytes("UTF-8"));
byte[] hexArray = {
(byte)'0', (byte)'1', (byte)'2', (byte)'3',
(byte)'4', (byte)'5', (byte)'6', (byte)'7',
(byte)'8', (byte)'9', (byte)'a', (byte)'b',
(byte)'c', (byte)'d', (byte)'e', (byte)'f'
};
byte[] hexChars = new byte[rawHmac.length * 2];
for ( int j = 0; j < rawHmac.length; j++ ) {
int v = rawHmac[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
catch (Exception ex) {
throw new RuntimeException(ex);
}
}
I get 0315a69471ebe855e9e221a374b30d8de08dcc833857f964737632698c87278e too.
In PHP with Pack function
$message = "hello world";
$key = "7E066";
echo hash_hmac('SHA256',$message, pack('H*',$key));
I get 33e97719c1b98f64bd0394e7fe94f43eae927e15f9eda15aeff0830bc3dd2fc3
I don't understand what pack function does, I can not write same function in Java. Could anyone help me please?
Try this:
public String pack(String hex) {
String input = hex.length() % 2 == 0 ? hex : hex + "0";
StringBuilder output = new StringBuilder();
for (int i = 0; i < input.length(); i+=2) {
String str = input.substring(i, i+2);
output.append((char)Integer.parseInt(str, 16));
}
return output.toString();
}
for this data it returns exactly that you need:
String data = "hello world";
String key = "7E066";
System.out.println(hmacSha(key,data, "HmacSHA256"));
System.out.println(hmacSha(pack(key), data, "HmacSHA256"));
0315a69471ebe855e9e221a374b30d8de08dcc833857f964737632698c87278e
33e97719c1b98f64bd0394e7fe94f43eae927e15f9eda15aeff0830bc3dd2fc3
The trick is that the pack() PHP function for input hexadecimal string of the odd length shift it to the left, i.e. add one zero to the right of the value. This is because it is only possible to calculate binary string for even-length input hexadecimal string.
In my case work only this:
import org.apache.geronimo.mail.util.Hex;
public class TestEncoding {
public static void main(String[] args) {
System.out.println(Hex.decode(("48398018")));
}
}
Result:
H9�
It was equivalent PHP code:
$nonce = 48398018;
pack('H*', $nonce);
echo $nonce;
Result: H9�
I have the following Java code to generate hashes based on input text.
package main;
import java.util.Scanner;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class String_Hash_Generator {
public static void main(String args[]) throws NoSuchAlgorithmException {
Scanner inputScanner = new Scanner(System.in);
System.out.print("Input: ");
String input = inputScanner.next();
/* MD2 */
MessageDigest objMD2 = MessageDigest.getInstance("MD2");
byte[] bytMD2 = objMD2.digest(input.getBytes());
BigInteger intNumMD2 = new BigInteger(1, bytMD2);
String hcMD2 = intNumMD2.toString(16);
while (hcMD2.length() < 32) {
hcMD2 = "0" + hcMD2;
}
/* MD5 */
MessageDigest objMD5 = MessageDigest.getInstance("MD5");
byte[] bytMD5 = objMD5.digest(input.getBytes());
BigInteger intNumMD5 = new BigInteger(1, bytMD5);
String hcMD5 = intNumMD5.toString(16);
while (hcMD5.length() < 32) {
hcMD5 = "0" + hcMD5;
}
/* SHA-1 */
MessageDigest objSHA1 = MessageDigest.getInstance("SHA-1");
byte[] bytSHA1 = objSHA1.digest(input.getBytes());
BigInteger intNumSHA1 = new BigInteger(1, bytSHA1);
String hcSHA1 = intNumSHA1.toString(16);
while (hcSHA1.length() < 40) {
hcSHA1 = "0" + hcSHA1;
}
/* SHA-256 */
MessageDigest objSHA256 = MessageDigest.getInstance("SHA-256");
byte[] bytSHA256 = objSHA256.digest(input.getBytes());
BigInteger intNumSHA256 = new BigInteger(1, bytSHA256);
String hcSHA256 = intNumSHA256.toString(16);
while (hcSHA256.length() < 64) {
hcSHA256 = "0" + hcSHA256;
}
/* SHA-384 */
MessageDigest objSHA384 = MessageDigest.getInstance("SHA-384");
byte[] bytSHA384 = objSHA384.digest(input.getBytes());
BigInteger intNumSHA384 = new BigInteger(1, bytSHA384);
String hcSHA384 = intNumSHA384.toString(16);
while (hcSHA384.length() < 96) {
hcSHA384 = "0" + hcSHA384;
}
/* SHA-512 */
MessageDigest objSHA512 = MessageDigest.getInstance("SHA-512");
byte[] bytSHA512 = objSHA512.digest(input.getBytes());
BigInteger intNumSHA512 = new BigInteger(1, bytSHA512);
String hcSHA512 = intNumSHA512.toString(16);
while (hcSHA512.length() < 128) {
hcSHA512 = "0" + hcSHA512;
}
System.out.println("\nMD2: " + hcMD2
+ "\nMD5: " + hcMD5
+ "\nSHA-1: " + hcSHA1
+ "\nSHA-256: " + hcSHA256
+ "\nSHA-384: " + hcSHA384
+ "\nSHA-512: " + hcSHA512);
}
}
The input needs to be Scanner, because it is essential that it is run in a Command Prompt.
How could a file hash generator be created that takes the file path, such as C:\Program Files\WinRAR\Rar.exe and generates the hashes (MD2, MD5, SHA-1, SHA-256, SHA-384, SHA-512)?
Edit: The only solutions I have been able to find only use the file's name, not the entire path.
First, you need a mechanism to print a byte[] as hex. From the top answer to How to convert a byte array to a hex string in Java? you can do,
final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
public static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
Then, you might use Files.readAllBytes(Path) to read your file(s). Finally, iterate an array of hash algorithms to calculate each hash. Something like,
public static void main(String args[]) {
Scanner inputScanner = new Scanner(System.in);
String[] hashAlgos = { "MD2", "MD5", "SHA-1", "SHA-256", "SHA-384", "SHA-512" };
System.out.print("Input: ");
String input = inputScanner.next();
try {
byte[] fileContents = Files.readAllBytes(new File(input).toPath());
for (String algo : hashAlgos) {
MessageDigest md = MessageDigest.getInstance(algo);
byte[] hash = md.digest(fileContents);
System.out.printf("%s %s%n", algo, bytesToHex(hash));
}
} catch (NoSuchAlgorithmException | IOException e) {
e.printStackTrace();
}
}
I am calculating the MD5 in PHP with following line (see documentation for more info):
md5($password, true); // returns raw output
I am using the following Java code:
byte[] bytesOfMessage = password.getBytes("UTF-8");
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] thedigest = md.digest(bytesOfMessage);
Above code doesn't return the same output as the one returned by the PHP code.
How can I solve it for Android/Java generate exactly the same MD5 with raw output not hash string?
Yes. I had the same problem. I find the right way:
That is my equivalent of PHP's md5(password, true):
final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
public byte[] md5x16(String text) {
try {
MessageDigest digester = MessageDigest.getInstance("MD5");
digester.update(text.getBytes());
byte[] md5Bytes = digester.digest();
String md5Text = new String(md5Bytes); // if you need in String format
// better use md5Bytes if applying further processing to the generated md5.
// Otherwise it may give undesired results.
return md5Bytes;
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
and equivalent of PHP's md5(password, false):
public static String md5(String text) {
try {
MessageDigest digester = MessageDigest.getInstance("MD5");
digester.update(text.getBytes());
byte[] md5Bytes = digester.digest();
String md5Text = null;
md5Text = bytesToHex(md5Bytes);
return md5Text;
}
catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
public static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
And if you need to convert an equivalent of PHP's base64_encode(text), use this one:
public String convertToBase64(byte[] bytes) {
try {
String base64 = Base64.encodeToString(bytes, Base64.DEFAULT);
return base64;
}
catch (Exception e) {
}
return "";
}
I had the same issue, this is my Java program code:
public static String encryptPassword(String password) {
String hash = null;
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(password.getBytes("UTF-8"));
byte[] raw = md.digest();
hash = (new BASE64Encoder()).encode(raw);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return hash;
}
And this is my php code:
<?php
$str = 'encodeIt';
$toutf8 = utf8_encode($str);
$var = md5($str,true);
echo base64_encode($var);
?>
They return always the same hash.