Convert hex string hash to base64 - string

I have a plaintext password "welcome2022".
Expected SHA1 hash is wjC4KfO5XfMIRhi45M/VA/0i8NA=
However, SHA1 hash method of sql is generating SHA1 hash in hex string format which is C230B829F3B95DF3084618B8E4CFD503FD22F0D0.
I intend to convert the the above hex string to the base64 encoded hash wjC4KfO5XfMIRhi45M/VA/0i8NA=.
Below is the groovy code for your reference.
def cleartext = SecurityUtil.decrypt(password) //Decrypts the value of a GuardedString.
def password_bytes = [0, 0, 0, 0, 0] as byte[]
password_bytes = SecurityUtil.charsToBytes(cleartext.toCharArray())
def password2 = SecurityUtil.computeBase64SHA1Hash(password_bytes) //Computes the base 64 encoded SHA1 hash of the input.
Then running the below sql query,
sql.eachRow("SELECT id FROM users WHERE userName = ? AND password =CONCAT('{SHA1}', ?)", [username, password2]) {
....
}
Logs do not show any errors when this groovy script is executed.
I am not sure if I am writing the code correct syntactically.

So this function will give you the base64 encoded SHA-1 hash of a given password:
def sha64(String password) {
password.digest('SHA-1').decodeHex().encodeBase64()
}
And if you do:
println sha64('welcome2022')
It prints
wjC4KfO5XfMIRhi45M/VA/0i8NA=

Related

How can I overwrite the automatically calculated kid when importing a JWK from PEM

I am trying to create a JWE Token using the node-jose library's createEncrypt method. The problem is, I want to set the kid to a certain value. But when importing the key using the jose.JWK.asKey method, it's automatically calculating the kid and won't let me change/set it. Here is the sample code:
const { JWK, JWE } = require('node-jose');
encrypt = async (raw, format = 'compact', contentAlg = "A128CBC-HS256", alg = "RSA-OAEP-256") => {
let _publicKey = `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxO+O52a1eAkbYatqpPAk
vhTz5VAdNloWhbmAmwPQl9202VKxU+yOCbwZSU8NqwVubHMgnxdycgJw+zGslXgz
zHPpmA5evOY2AVjpcE9avKfp523M5gxOaAnQCxat6KxORIJWLSF84EUtrzLIxgle
bvDyhfoHMGVSYiP89UQPTR+uu6irFRkdu2zFDPOx2/4XdtyAbJlWdj4Fes0v3CcA
/jDO9EmwVEiySCuagLWnrvHvCV0mCDN167JSVjeeKZy4Q36WyF0VqytxmW+mXn+m
IfcLlj5vXSXp81pI1Iyg86KZtW3A6dP8QuRlYwHJU7Z+m7AeIHtC+ol0/eBPYPwk
PQIDAQAB
-----END PUBLIC KEY-----`
let publicKey = await JWK.asKey(_publicKey, "pem");
publicKey.kid = "932ea6bb-2623-4dc3-96b1-c4be61e97569";
console.log(publicKey)
const buffer = Buffer.from(JSON.stringify(raw))
const encrypted = await JWE.createEncrypt({ format: format, contentAlg: contentAlg, fields: { alg: alg, iat: (new Date().getTime()), exp: 30000} }, publicKey)
.update(buffer).final();
return encrypted;
}
let raw = {
"mobileNumber": "1234567890",
"customerId": "000000000",
"sessionId": "3a600342-a7a3-4c66-bbd3-f67de5d7096f",
};
encrypt(raw).then((data)=> {console.log(data)})
Here is the encrypted JWE Token generated:
eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJpYXQiOjE2NDAyNDU0NzY5ODEsImV4cCI6MzAwMDAsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJraWQiOiI1bUxtdmVHdng0RHVucGlfTnBhajhxZlByRHNDYW9NV29JeWRoM003SzA4In0.SUpO7X0XXbkqQtNGVvLMNo6oGi1GrTzAR1FtXlL8ngg9Uvd91nkLiRqgcmjKBBEE1M330WV_HrUYNs2NVRcXTDcr41fSwvHSu7veK_YDj-m73LoMKlmojeB6GIRUIXIw7oaqgFSOSb_Xgq_zwG9WGa07h2OgOzeFxKNJCvt1J2i_v2Tt61yyet0hdMinT78whDGgf_JW4LUSaXY9wsqsuQSDkKWFLvxHqNmq7nGPLpgEJjm1GPF0slPvdWsARsMEttbPK9VpoMUvMcqy5bWVWSmj2MEGTVw6ua-uFw9fEgyn095wl-s8lEfZFkFaiFN7ps5VwqVV2tihpnYrCVIYAA.jxR4Gw_Gcy9Sexw-wMBKtQ.TzugQZCFgQiolIBc2FAEQ0ZbvNdPFzE2z0m9cFxWQtADEijOCzQjZreVvnsVjHFXdP_w-YcnCbmKXkwalWnFMo7wkjuuJ0fAsTfTOEiBjuIPvMa0k04C97Rc4ZYszzzL7xxwW0RnqoNxiQMkea3H0A.qAqgcg_DLV1vHzb0EIq-9A
If you check this on jwt.io, you can see the kid is already calculated & set. How can I set/change the kid here?
The kid is calculated automatically, when it's not known during the import:
When importing or generating a key that does not have a "kid" defined, a "SHA-256" thumbprint is calculated and used as the "kid".
(see https://github.com/cisco/node-jose#obtaining-a-keys-thumbprint)
But in the call to JWK.asKey, you can pass an additional parameter extras, that sets values for existing fields or contains additional fields for the JWK.
For your use case, you can set a kid as a JSON object
let kid = "932ea6bb-2623-4dc3-96b1-c4be61e97569";
let publicKey = await JWK.asKey(_publicKey, "pem", {"kid":kid});
console.log(publicKey.toJSON())
Output:
{
kty: 'RSA',
kid: '932ea6bb-2623-4dc3-96b1-c4be61e97569',
n: 'xO-O52a1eAkbYatqpPAkvhTz5VAdNloWhbmAmwPQl9202VKxU-yOCbwZSU8NqwVubHMgnxdycgJw-zGslXgzzHPpmA5evOY2AVjpcE9avKfp523M5gxOaAnQCxat6KxORIJWLSF84EUtrzLIxglebvDyhfoHMGVSYiP89UQPTR-uu6irFRkdu2zFDPOx2_4XdtyAbJlWdj4Fes0v3CcA_jDO9EmwVEiySCuagLWnrvHvCV0mCDN167JSVjeeKZy4Q36WyF0VqytxmW-mXn-mIfcLlj5vXSXp81pI1Iyg86KZtW3A6dP8QuRlYwHJU7Z-m7AeIHtC-ol0_eBPYPwkPQ',
e: 'AQAB'
}

Node-Forge: how can I convert the public key's modulo and exponent from decimal to hex?

I'm using node forge (https://www.npmjs.com/package/node-forge) to create a public and private key pair (nodeforge.pki.rsa.generateKeyPair()) for testing purposes. The modulo (n) and exponent (e) of the public key is represented as an array of decimal values. However, the service that will provide the public key for encryption in production represents modulo and exponent in hex values. My question now is, how can I easily transform these values created by node forge from decimal to hex (I then want to use these values in NodeRSA (https://github.com/rzcoder/node-rsa)):
let pair = nodeforge.pki.rsa.generateKeyPair();
var key = new NodeRSA();
key.importKey({
n: new Buffer(pair.publicKey.n.data, 'hex'),
e: new Buffer(pair.publicKey.e.data, 'hex')
});
The format of the public key provided by node forge is:
"publicKey": {
"n": {
"data": [
95452259,
62292680,
234781115,
46168802,
112578909,
58538647,
44874864,
186853653,
197342112,
104676488,
229032986,
262511790,
101189381,
134141598,
55892282,
145717908,
78729040,
107967002,
62922480,
120440374,
262852613,
65361518,
128040269,
29796715,
171859902,
201093939,
131227011,
165441987,
9273795,
130804401,
240125365,
221986724,
32034899,
180589760,
106981089,
188935555,
21820073,
96309166,
54553752,
100808208,
198611546,
11382488,
139519439,
212193674,
26780810,
225883560,
101310123,
78467199,
181998612,
8435669,
195696345,
41284550,
129888967,
137003722,
74415901,
92893643,
57787310,
143216416,
42433969,
100838107,
34667532,
136300465,
185624737,
67347,
93800454,
226047286,
76852009,
57120535,
266741908,
27775411,
39685199,
4113773,
214629603,
12
],
"t": 74,
"s": 0
},
"e": {
"data": [
65537
],
"t": 1,
"s": 0
}
The reason I want to do that is that I want to test if the encryption facility works correctly (first, encrypt a value with the public key, then decrypt the value with the private key again), because the public key is provided by an external party and else I have no possibility to check, as the private key is not provided.
Thanks a lot in advance!
You can use toString(16) to convert to hexadecimal
var nHex = publicKey.n.toString(16);
var eHex = publicKey.e.toString(16);

Google OpenID Connect Public Keys

What exactly does the response from https://www.googleapis.com/oauth2/v3/certs mean? I am trying to verify a JWT I got via the Google OpenID Connect process using node-jsonwebtokens and the key used to verify the signature must be one of those two. The source code however suggests that node-jsonwebtokens awaits a different key format than available in the response:
[
{
'kty': 'RSA',
'alg': 'RS256',
'use': 'sig',
'kid': 'e53139984bd36d2c230552441608cc0b5179487a',
'n': 'w5F_3au2fyRLapW4K1g0zT6hjF-co8hjHJWniH3aBOKP45xuSRYXnPrpBHkXM6jFkVHs2pCFAOg6o0tl65iRCcf3hOAI6VOIXjMCJqxNap0-j_lJ6Bc6TBKgX3XD96iEI92iaxn_UIVZ_SpPrbPVyRmH0P7B6oDkwFpApviJRtQzv1F6uyh9W_sNnEZrCZDcs5lL5Xa_44-EkhVNz8yGZmAz9d04htNU7xElmXKs8fRdospyv380WeaWFoNJpc-3ojgRus26jvPy8Oc-d4M5yqs9mI72-1G0zbGVFI_PfxZRL8YdFAIZLg44zGzL2M7pFmagJ7Aj46LUb3p_n9V1NQ',
'e': 'AQAB'
},
{
'kty': 'RSA',
'alg': 'RS256',
'use': 'sig',
'kid': 'bc8a31927af20860418f6b2231bbfd7ebcc04665',
'n': 'ucGr4fFCJYGVUwHYWAtBNclebyhMjALOTUmmAXdMrCIOgT8TxBEn5oXCrszWX7RoC37nFqc1GlMorfII19qMwHdC_iskju3Rh-AuHr29zkDpYIuh4lRW0xJ0Xyo2Iw4PlV9qgqPJLfkmE5V-sr5RxZNe0T1jyYaOGIJ5nF3WbDkgYW4GNHXhv-5tOwWLThJRtH_n6wtYqsBwqAdVX-EVbkyZvYeOzbiNiop7bDM5Td6ER1oCBC4NZjvjdmnOh8-_x6vB449jL5IRAOIIv8NW9dLtQd2DescZOw46HZjWO-zwyhjQeYY87R93yM9yivJdfrjQxydgEs8Ckh03NDATmQ',
'e': 'AQAB'
}
]
It doesn't have the classical BEGIN PUBLIC KEY block, is it maybe encoded? Is there an additional step needed?
That code indeed deals with PEM-formatted certificates/keys instead of the JSON Web Key (JWK) formatted key material that is published by Google on the URL that you gave.
There is however a different URL that serves the (same) key material in PEM format here: https://www.googleapis.com/oauth2/v1/certs. You can use that representation in node-jsonwebtoken.
I was able to use n and e successfully with the following code, and then create a public key in Java to decode a JWT which was sent by Google.
String n_str = "...string value of n.... ";
String e_str = "... string value of e...";
byte[] n_bytes = Base64.getUrlDecoder().decode(n_str);
byte[] e_bytes = Base64.getUrlDecoder().decode(e_str);
BigInteger n = new BigInteger(1, n_bytes);
BigInteger e = new BigInteger(1, e_bytes);
RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec(n,e);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);

transforming strings in a golang struct

I've got a json file of AES encrypted secrets. The structure is:
{
"username": "asdf123ASLdf3",
"password": "elisjdvo4etQW"
}
And a struct to hold these values
type Secrets struct {
Username string `json:"username"`
Password string `json:"password"`
}
It's easy to load the encrypted json values into the struct, but what I really want is a struct with the unencrypted values.
So, for each value, I'd like to run it though a function:
aesDecrypt(key string, value string) string
I'm happy to have this done on the first load, or to move everything over into a new struct.
I would like to avoid repeating the json keys or the field names.
What's the best way to do this?
(Also open to other ways to manage encrypted secrets in Go)
One option is to define a custom JSON Unmarshaler. Another is, as you mention, copy it to another struct.
Implementing the Unmarshaler interface
The key insight is knowing that you can override json.Unmarshal's
behaviour by implementing the Unmarshaler interface. In our
case, that means defining a function func (ss *Secrets)
UnmarshalJSON(bb []byte) error that will do the AES Decryption when
you try to unmarshal any JSON to a Secrets.
package main
import "fmt"
import "encoding/json"
type Secrets struct {
Username string `json:"username"`
Password string `json:"password"`
}
func main() {
jj := []byte(`{
"username": "asdf123ASLdf3",
"password": "elisjdvo4etQW"
}`)
var ss Secrets
json.Unmarshal(jj, &ss)
fmt.Println(ss)
}
func aesDecrypt(key, value string) string {
return fmt.Sprintf("'%s' decrypted with key '%s'", value, key)
}
func (ss *Secrets) UnmarshalJSON(bb []byte) error {
var objmap map[string]*string
err := json.Unmarshal(bb, &objmap)
ss.Username = aesDecrypt("my key", *objmap["password"])
ss.Password = aesDecrypt("my key", *objmap["username"])
return err
}
This outputs a Secrets struct:
{'elisjdvo4etQW' decrypted with key 'my key'
'asdf123ASLdf3' decrypted with key 'my key'}
See it in action at the Go Playground.
Copying to another struct
You could simply make a new Secrets struct every time you need to
decrypt the JSON. This could be tedious if you do it alot, or if you
have no need for the intermediate state.
package main
import "fmt"
import "encoding/json"
type Secrets struct {
Username string `json:"username"`
Password string `json:"password"`
}
func main() {
jj := []byte(`{
"username": "asdf123ASLdf3",
"password": "elisjdvo4etQW"
}`)
var ss Secrets
json.Unmarshal(jj, &ss)
decoded := Secrets{
aesDecrypt(ss.Username, "my key"),
aesDecrypt(ss.Password, "my key")}
fmt.Println(decoded)
}
func aesDecrypt(key, value string) string {
return fmt.Sprintf("'%s' decrypted with key '%s'", value, key)
}
Check it out at Go Playground.
This has the same output as above:
{'elisjdvo4etQW' decrypted with key 'my key'
'asdf123ASLdf3' decrypted with key 'my key'}
Obviously, you would use a different version of aesDecrypt, mine's
just a dummy. And, as always, you should actually be checking the
returned errors in your own code.

Password encryption algorithm

I want to develop a web application where users can login inserting their email and password (chosen when register). I want to know which would be the best password hashing algorithm. I have read that bcrypt is a good option, but what algorithm do sites like facebook use?
You'll want to store a hash and a salt in your database and use those for authentication. This article in particular was very helpful for me when I implemented this: http://www.codeproject.com/Articles/704865/Salted-Password-Hashing-Doing-it-Right
You should never store a password, even if it is encrypted. Because something that is encrypted can be descrypted, so an attacker could do the same.
Google for "hashing" and "salting", perhaps OWASP has some recommendations how to do this properly. Storing encrypted passwords will be on the list of vulnerabilities to avoid, I think.
I have written an 2 functions for handling passwords. The first one accepts a string (i.e. your password) and returns a seeded hash. It takes an MD5 hash of the time and prepends it to the string. It then takes a SHA256 hash of that string. It then prepends the original MD5 hash to the SHA256 hash. The function returns this 96-character string. The second function takes 2 strings as this arguments (the password being tested and the password hash you are tested it against) and returns a Boolean value. This is PHP, but the logic is of course transferable.
function hash_password( $password ){
$md5 = strtoupper( hash( 'md5', time() ) );
$hash = $md5 . strtoupper( hash( 'sha256', $md5 . $password ) );
return $hash;
}
function test_password( $password, $hash ){
$md5 = substr( $hash, 0, 32 );
$sha256 = substr( $hash, 32 );
if( $sha256 == strtoupper( hash( 'sha256', $md5 . $password ) ) )
return true;
else
return false;
}

Resources