Howto get the right sha1 value, that is recoginsed by haveibeenpawned? - hash

i want to check my passwords with help of the sha1-hashed pw files from haveibeenpawned. And of course I want to do it locally ;-). In order to be able to compare those hashes with a sha1-hash, that i created from a password, I used two different approaches:
php:
$pw='1234';
$pwhash = strtoupper(sha1($pw));
c:
char pw[] = "1234";
size_t pwlen = sizeof(pw);
SHA1(pw, pwlen, pwhash);
// and convert binary to Hex-string "02X" ...
First question is: Why the hashes are different? Is there a hidden salt?
And why the won't match with the hashes of Troy Hunt?
[Update] Meanwhile the php hash is matched in the list. I didn't limit the string to 40 chars and had "\r" and "\n" in it.

You're computing the SHA1 hashes of two different chunks of data.
In your PHP code:
$pw='1234';
$pwhash = strtoupper(sha1($pw));
you are, I presume, computing the hash of a 4-byte sequence (I don't know PHP very well). The result should be 7110eda4d09e062aa5e4a390b0a572ac0d2c0220.
In your C code (which is incomplete, BTW; where does this SHA function come from?):
char pw[] = "1234";
size_t pwlen = sizeof(pw);
SHA1(pw, pwlen, pwhash);
pwlen is 5, not 4, because applying sizeof to a string literal gives you the length of the string plus 1 for the terminating '\0' character. You're computing the SHA1 sum of the sequence {'1', '2', '3', '4', '\0'}, which should be 8bef71a3d039e425fe43872cc178441c206b3fda.
Try this:
char pw[] = "1234";
SHA1(pw, strlen(pw), pwhash);
In your C code (which is incomplete, BTW; where does this SHA function come from?):
char pw[] = "1234";
size_t pwlen = sizeof(pw);
SHA1(pw, pwlen, pwhash);
pwlen is 5, not 4, because applying sizeof to a string literal gives you the length of the string plus 1 for the terminating '\0' character. You're computing the SHA1 sum of the sequence {'1', '2', '3', '4', '\0'}, which should be 8bef71a3d039e425fe43872cc178441c206b3fda.
Try this:
char pw[] = "1234";
SHA1(pw, strlen(pw), pwhash);
A simpler way to get the SHA1 checksum of a given password, if you're on a Unix-like system or have an sha1sum1 command installed, is:
echo -n 'your_password' | sha1sum
If you want to remove the ' -' at the end of the output line, you can pipe the output through sed;
echo -n 'your password' | sha1sum | sed 's/ .*//'

Related

How to replace groups of characters between flags in MATLAB

Suppose I have a char variable in Matlab like this:
x = 'hello ### my $ name is Sean Daley.';
I want to replace the first '###' with the char '&', and the first '$' with the char '&&'.
Note that the character groups I wish to swap have different lengths [e.g., length('###') is 3 while length('&') is 1].
Furthermore, if I have a more complicated char such that pairs of '###' and '$' repeat many times, I want to implement the same swapping routine. So the following:
y = 'hello ### my $ name is ### Sean $ Daley ###.$.';
would be transformed into:
'hello & my && name is & Sean && Daley &.&&.'
I have tried coding this (for any arbitrary char) manually via for loops and while loops, but the code is absolutely hideous and does not generalize to arbitrary character group lengths.
Are there any simple functions that I can use to make this work?
y = replace(y,["###" "$"],["&" "&&"])
The function strrep is what you are looking for.

Convert a string into hash value in matlab

How can I convert a message into a hash value using SHA/MD5 hashing in MATLAB? is there any builtin function or any fixed code?
There are no functions in matlab to calculate hashes. However, you can call Java (any OS) or .Net (Windows only) functions directly from matlab and either of these implement what you want.
Note that you haven't specified the encoding of the string. The hash is different if you consider the string in ASCII, UTF8, UTF16, etc.
Also note that matlab does not have 160-bit or 256-bit integer, so the hash can't obviously be a single integer.
Anyway, using .Net:
SHA256
string = 'some string';
sha256hasher = System.Security.Cryptography.SHA256Managed;
sha256 = uint8(sha256hasher.ComputeHash(uint8(string)));
dec2hex(sha256)
SHA1
sha1hasher = System.Security.Cryptography.SHA1Managed;
sha1= uint8(sha1hasher.ComputeHash(uint8(string)));
dec2hex(sha1)
Java based solution can be found in the following link
https://www.mathworks.com/matlabcentral/answers/45323-how-to-calculate-hash-sum-of-a-string-using-java
MATLAB's .NET classes appear to be a more recent creation than the JAVA hashing.
However, these classes don't have much/any public documentation available. After playing with it a bit, I found a way to specify one of several hash algorithms, as desired.
The "System.Security.Cryptography.HashAlgorithm" constructor accepts a hash algorithm name (string). Based on the string name you pass in, it returns different hasher classes (.SHA256Managed is only one type). See the example below for a complete string input ==> hash string output generation.
% Available options are 'SHA1', 'SHA256', 'SHA384', 'SHA512', 'MD5'
algorithm = 'SHA1';
% SHA1 category
hasher = System.Security.Cryptography.HashAlgorithm.Create('SHA1'); % DEFAULT
% SHA2 category
hasher = System.Security.Cryptography.HashAlgorithm.Create('SHA256');
hasher = System.Security.Cryptography.HashAlgorithm.Create('SHA384');
hasher = System.Security.Cryptography.HashAlgorithm.Create('SHA512');
% SHA3 category: Does not appear to be supported
% MD5 category
hasher = System.Security.Cryptography.HashAlgorithm.Create('MD5');
% GENERATING THE HASH:
str = 'Now is the time for all good men to come to the aid of their country';
hash_byte = hasher.ComputeHash( uint8(str) ); % System.Byte class
hash_uint8 = uint8( hash_byte ); % Array of uint8
hash_hex = dec2hex(hash_uint8); % Array of 2-char hex codes
% Generate the hex codes as 1 long series of characters
hashStr = str([]);
nBytes = length(hash_hex);
for k=1:nBytes
hashStr(end+1:end+2) = hash_hex(k,:);
end
fprintf(1, '\n\tThe %s hash is: "%s" [%d bytes]\n\n', algorithm, hashStr, nBytes);
% SIZE OF THE DIFFERENT HASHES:
% SHA1: 20 bytes = 20 hex codes = 40 char hash string
% SHA256: 32 bytes = 32 hex codes = 64 char hash string
% SHA384: 48 bytes = 48 hex codes = 96 char hash string
% SHA512: 64 bytes = 64 hex codes = 128 char hash string
% MD5: 16 bytes = 16 hex codes = 32 char hash string
REFERENCES:
1) https://en.wikipedia.org/wiki/SHA-1
2) https://defuse.ca/checksums.htm#checksums
I just used this and it works well.
Works on strings, files, different data types.
For a file I compared against CRC SHA through file explorer and got the same answer.
https://www.mathworks.com/matlabcentral/fileexchange/31272-datahash

How does Perl store integers in-memory?

say pack "A*", "asdf"; # Prints "asdf"
say pack "s", 0x41 * 256 + 0x42; # Prints "BA" (0x41 = 'A', 0x42 = 'B')
The first line makes sense: you're taking an ASCII encoded string, packing it into a string as an ASCII string. In the second line, the packed form is "\x42\x41" because of the little endian-ness of short integers on my machine.
However, I can't shake the feeling that somehow, I should be able to treat the packed string from the second line as a number, since that's how (I assume) Perl stores numbers, as little-endian sequence of bytes. Is there a way to do so without unpacking it? I'm trying to get the correct mental model for the thing that pack() returns.
For instance, in C, I can do this:
#include <stdio.h>
int main(void) {
char c[2];
short * x = c;
c[0] = 0x42;
c[1] = 0x41;
printf("%d\n", *x); // Prints 16706 == 0x41 * 256 + 0x42
return 0;
}
If you're really interested in how Perl stores data internally, I'd recommend PerlGuts Illustrated. But usually, you don't have to care about stuff like that because Perl doesn't give you access to such low-level details. These internals are only important if you're writing XS extensions in C.
If you want to "cast" a two-byte string to a C short, you can use the unpack function like this:
$ perl -le 'print unpack("s", "BA")'
16706
However, I can't shake the feeling that somehow, I should be able to treat the packed string from the second line as a number,
You need to unpack it first.
To be able to use it as a number in C, you need
char* packed = "\x42\x41";
int16_t int16;
memcpy(&int16, packed, sizeof(int16_t));
To be able to use it as a number in Perl, you need
my $packed = "\x42\x41";
my $num = unpack('s', $packed);
which is basically
use Inline C => <<'__EOI__';
SV* unpack_s(SV* sv) {
STRLEN len;
char* buf;
int16_t int16;
SvGETMAGIC(sv);
buf = SvPVbyte(sv, len);
if (len != sizeof(int16_t))
croak("usage");
Copy(buf, &int16, 1, int16_t);
return newSViv(int16);
}
__EOI__
my $packed = "\x42\x41";
my $num = unpack_s($packed);
since that's how (I assume) perl stores numbers, as little-endian sequence of bytes.
Perl stores numbers in one of following three fields of a scalar:
IV, a signed integer of size perl -V:ivsize (in bytes).
UV, an unsigned integer of size perl -V:uvsize (in bytes). (ivsize=uvsize)
NV, a floating point numbers of size perl -V:nvsize (in bytes).
In all case, native endianness is used.
I'm trying to get the correct mental model for the thing that pack() returns.
pack is used to construct "binary data" for interfacing with external APIs.
I see pack as a serialization function. It takes as input Perl values, and outputs a serialized form. The fact the output serialized form happens to be a Perl bytestring is more of an implementation detail than a core functionality.
As such, all you're really expected to do with the resulting string is feed it to unpack, though the serialized form is convenient to have it move around processes, hosts, planets.
If you're interested in serializing it to a number instead, consider using vec:
say vec "BA", 0, 16; # prints 16961
To take a closer look at the string's internal representation, take a look at Devel::Peek, though you're not going to see anything surprising with a pure ASCII string.
use Devel::Peek;
Dump "BA";
SV = PV(0xb42f80) at 0xb56300
REFCNT = 1
FLAGS = (POK,READONLY,pPOK)
PV = 0xb60cc0 "BA"\0
CUR = 2
LEN = 16

Perl mantissa differ from other doubles

I'm trying to scan in a float: 13.8518009935297 .
The first routine is my own, the second is MacOSX libc's
strtod, the third is GMP's mpf_get_d() the forth is
perls numeric.c:Perl_my_atof2().
I use this snippet to print the mantissa:
union ieee_double {
struct {
uint32_t fracl;
uint32_t frach:20;
uint32_t exp:11;
uint32_t sign:1;
} s;
double d;
uint64_t l;
};
union ieee_double l0;
l0.d = ....
printf("... 0x%x 0x%x\n", l0.s.frach, l0.s.fracl);
The return values for the four functions are:
my-func : 0xbb41f 0x4283d21b
strtod : 0xbb41f 0x4283d21c
GMP : 0xbb41f 0x4283d21b
perl : 0xbb41f 0x4283d232
The difference between the first three functions is rounding.
However perl's mantissa is quite out of sync.
If I print all four doubles to a string again I get the
same decimal double back, the numbers seem to be equal.
My question:
The difference between my-func, strtod, GMP is rounding. However,
why is perl's mantissa so much out of sync, but still, if
converted back to decimal, it ends up as the same number again.
The difference is 22, so it should be noted in a decimal
fraction. How can I explain this?
Append:
Sorry, I think I figured out the problem:
$r = rand(25);
$t = $p->tokenize_str("$r");
tokenize_str() was my implementation of a conversion from string to double.
However the perl stringify "$r" prints out $r as 13.8518009935297, which is a
already truncation.
The actual value of $r is different, so when I at the end the binaries of
$t with $r I get values that diverge.
Here is some perl code to answer your question:
perl -le '($frac1, $frach)=unpack("II", pack "d", .0+"13.8518009935297");
print sprintf("%d %d 0x%03x 0x%04x", ($frach >> 31)&1, ($frach>>20)&0x5ff, $frach & 0xfffff, $frac1)'
-> 0 1026 0xbb41f 0x4283d21c
Perl gives the same result as strtod. The difference was the mistake you indicated in append.

Calculating SHA1 hash of a 'nvarchar' string using T-SQL

I'm trying to calculate SHA1 hash of a unicode string using T-SQL. The below code works fine with ASCII strings:
declare #input varchar(50)
set #input = 'some text'
print 'SHA1 Hash: ' + UPPER(master.dbo.fn_varbintohexsubstring(0, HashBytes('SHA1', #input), 1, 0))
but it calculates wrong hash when I replace first line of code with declare #input nvarchar(50).
Calculated hash (nvarchar): BBA91B680CE2685E9465DE24967E425CF055B10F
Calculated hash by a tool : 37AA63C77398D954473262E1A0057C1E632EDA77
How can I calculate SHA1 hash of a nvarchar ?
[EDIT]:
Below C# code generate same hash as the tool I use for hashing:
// Computes SHA1 hash of a given string
string ComputeHash(string input)
{
string result = string.Empty;
byte[] hash;
byte[] bytes = Encoding.GetBytes(input);
using (var sha = SHA1Managed.Create())
hash = sha.ComputeHash(bytes);
foreach (var b in hash)
result += b.ToString("X2");
return result;
}
Are you sure that the hash returned by your tool is using UTF16 or Unicode encoding when you compare it with the one returned by SQL Server?...SHA1 (and other encoding formats) depends on the data type, so it should return different values when given as an input. Take a look at this link for a more detailed explanation.