QT Blowfish Charset - c++

I need use Blowfish for check password into a database using by CMS.
I work with QBlowfish because I thinking basic class and easy to use but no, I have a problem :
I crypt same string ("AfuYeew7l") with same salt ("$2y$04$pzmGaIWodB/7jTZ8Y.082u")
When I use C++, I have : ("G?(?"?WIk???*?")
So when I use PHP, I have good hash : ("$2y$04$pzmGaIWodB/7jTZ8Y.082uA15Z.5VwrLXiBPebxNZ2ET75NqX1QOq")
My slot who hash :
QByteArray key = NULL;
QByteArray crypt = NULL;
QByteArray pass(ui->_Input_Pass_Clair->text().toLocal8Bit()); // Clear Password
QByteArray hash(ui->_Label_Retour_Hash->text().toLocal8Bit()); // Crypt Password
key.push_back(ui->_Label_Retour_ID->text().toLocal8Bit()); // SALT
key.push_back(ui->_Label_Retour_CA->text().toLocal8Bit()); // SALT
key.push_back(ui->_Label_Retour_SEL->text().toLocal8Bit()); // SALT
key.push_back("$"); // SALT
QBlowfish fish(key);
fish.setPaddingEnabled(true);
crypt = fish.encrypted(pass);
ui->_Label_Retour_Pass_Crypte->setText(crypt);
I think crypt is not on correct formated or also key is not correct formated but I haven't anything idea for correct this
I join source code if necessary

Related

Convert QByteArray to QString

I want to encrypt the data of a database and to do this, I used AES_128 in this link for encryption.
The result of encryption is a QByteArray and the QByteArray is saved on the text file in the correct shape and I could decode it correctly, but and I need to convert it to the QString and reverse to QByteArray to store and read it on the Sqlite DB. I tried some options like
QByteArray encodedText; QString DataAsString = QString(encodedText);
and
string DataAsString1 = encodedText.toStdString();
and
QString DataAsString = QTextCodec::codecForName("UTF-8") >toUnicode(encodedText);
and other solutions like this link, but the outputs of these options aren't in the correct way. Because after casting, I couldn't convert the encoded text to decoded correctly.
This is the input string of encoded text:
"\x14r\xF7""6#\xFE\xDB\xF0""D\x1B\xB5\x10\xEDx\xE1""F"
and these are the outputs for the different options:
\024r�6#���D\033�\020�x�F
and
\024r�6#���D\033�\020�x�F
Does anybody suggestion about the right conversion?
try to use this:
QString QString::fromUtf8(const QByteArray &str)

Invalid Hash Function Name on SHA2-512 when creating user

Trying to create user using from golang using library "google.golang.org/api/admin/directory/v1"
As docs sad here https://developers.google.com/admin-sdk/directory/reference/rest/v1/users#User hashFunction could be MD5, DES, SHA2-256, SHA2-512, so i'm writing code:
hash := sha512.Sum512([]byte("random password value))
encoded := hex.EncodeToString(hash[:])
payload := &admin.User{
Password: "$6$" + encoded,
HashFunction: "SHA2-512"
}
This results: googleapi: Error 400: Invalid Hash Function Name, invalid
So how to understand, whats wrong with hash function name ?
So, i found here https://developers.google.com/resources/api-libraries/documentation/admin/directory_v1/python/latest/admin_directory_v1.users.html#insert that right now only supported SHA-1, crypt and MD5, so documentation is wrong, and for SHA2 hashes use string "crypt" as hashFunction value and add to password corresponding crypt prefix ( for example for SHA2-512 add $6$ to hex encoded value )

JJWT: How to parse claims correctly?

I made a test JWT using something like the following code
String jwt = Jwts.builder()
.setHeaderParam("typ", "jwt")
.setId("myid")
.setIssuer("ExampleIssuer")
.setSubject("JohnDoe")
.setIssuedAt(Date.from(LocalDateTime.now().toInstant(ZoneOffset.ofHours(-4))))
.setExpiration(Date.from(LocalDateTime.now().toInstant(ZoneOffset.ofHours(-4)).plusSeconds(600)))
.claim("perms",perms)
.signWith(SignatureAlgorithm.HS512, "SECRET")
.compact();
"perms" is a custom claim, which contains an ArrayList of Strings (permissions).
So when I receive the JWT back, I use the following code
try{
Jwt<?, ?> claims = Jwts.parser().setSigningKey("SECRET").parse(jwt);
System.out.println(claims.getBody().toString());
} catch (SignatureException e){
//Error
}
And I get something like
{jti=myid, iss=ExampleIssuer, sub=JohnDoe, iat=1495678299, exp=1495678899, perms=[CREATE, VIEW]}
My question is: is this the correct (intended) way to get the claims back? It seems from now I will need to parse the result with a custom method, but I think somehow that is not the intended way.
Thank you.`
I found a solution, not sure if the intended one, but it works. I need to use
Claims claims = new DefaultClaims();
try{
claims = Jwts.parser().setSigningKey("SECRET").parseClaimsJws(jwt).getBody();
} catch (SignatureException e){
//Signature error
}
I can use Map methods on claims, but also the built-in methods to recover the individual claims:
String jti = claims.getId();
String iss = claims.getIssuer();
String sub = claims.getSubject();
String iat = claims.getIssuedAt().toString();
String exp = claims.getExpiration().toString();
#SuppressWarnings("unchecked")
ArrayList<String> perms = (ArrayList<String>) claims.get("perms");
I think I can suppress the warning on the unchecked casting because since I created the custom claim with the same value class, I know what to expect on it. Now the claims in the token are parsed correctly into variables I can work with.

MD4 hashing with Crypto++ results in wrong hash?

I'm using Crypto++ to generate a MD4-Hash from a given password. But the generated hash doesn't seem to be correct. I think I'm misusing the CryptoPP functions somewhere.
CryptoPP::Weak1::MD4 hash2;
byte digest2[CryptoPP::Weak1::MD4::DIGESTSIZE];
hash.CalculateDigest(digest2, (byte*)password, strlen(password));
CryptoPP::HexEncoder encoder2;
std::string output2;
encoder2.Attach(new CryptoPP::StringSink(output2));
encoder2.Put(digest,sizeof(digest2));
encoder2.MessageEnd();
printf("END %s \n", output2.c_str());
My variable password contains the value "test". The printed output is:
END 3CC942AE509EC070B2548515E00F8CE8
The expected value, tested by some MD4 Hash Generators, is:
db346d691d7acc4dc2625db19f9e3f52
Any ideas?
Okay, I found the solution by myself. It doesn't work the way I posted above.
Here the correct code, it may be useful for someone else:
std::string value;
CryptoPP::Weak1::MD4 hashmd4;
CryptoPP::StringSource (password, true,
new CryptoPP::HashFilter( hashmd4,
new CryptoPP::HexEncoder(
new CryptoPP::StringSink(value)
)
)
);
hash.CalculateDigest(digest2, (byte*)password, strlen(password));
This should be:
hash2.CalculateDigest(digest2, (byte*)password, strlen(password));
That is, hash2, not hash.
encoder2.Put(digest,sizeof(digest2));
This should be:
encoder2.Put(digest2,sizeof(digest2));
That is, digest2, not digest.
The expected value, tested by some MD4 Hash Generators, is:
db346d691d7acc4dc2625db19f9e3f52
Yep, that's what I get using the code you posted after the typos were fixed.

Authenticating DotNetNuke Users in ColdFusion

Is there any way to authenticate users from other web apps using the DNN logins?
We have a main site that is using DNN and user logins are stored in the asp net membership table. From what I have been reading, the passwords are encrypted using the machine key and then salted. I see where this info is, but can't seem to encrypt passwords correctly using this method.
I'm trying with a Coldfusion web application on the same server where our DNN site is, but it doesn't want to work. You'd think it would be strait forward with the ColdFusion encryption function:
Encrypt(passwordstring, key [, algorithm, encoding, IVorSalt, iterations])
No matter what I try, I never get a matching value.
Any help, insight or pointing me in the right direction would be greatly appreciated!
(Edit: Original answer did not work in all cases. Substantially revised ...)
From what I have read, DNN uses an "SHA1" hash by default. The thread #barnyr posted shows it simply hashes the concatenated salt and password, but with a few twists.
DNN uses UTF-16LE to extract the password bytes, rather than CF's typical UTF-8.
It also extracts the salt and password bytes separately, which may produce different results than just decoding everything as a single string, which is what hash() does. (See demo below)
Given that CF9's Hash function does not accept binary (supported in CF11), I do not think it is possible to duplicate the results with native CF functions alone. Instead I would suggest decoding the strings into binary, then using java directly:
Code:
<cfscript>
thePassword = "DT!#12";
base64Salt = "+muo6gAmjvvyy5doTdjyaA==";
// extract bytes of the salt and password
saltBytes = binaryDecode(base64Salt, "base64");
passBytes = charsetDecode(thePassword, "UTF-16LE" );
// next combine the bytes. note, the returned arrays are immutable,
// so we cannot use the standard CF tricks to merge them
ArrayUtils = createObject("java", "org.apache.commons.lang.ArrayUtils");
dataBytes = ArrayUtils.addAll( saltBytes, passBytes );
// hash binary using java
MessageDigest = createObject("java", "java.security.MessageDigest").getInstance("SHA-1");
MessageDigest.update(dataBytes);
theBase64Hash = binaryEncode(MessageDigest.digest(), "base64");
WriteOutput("theBase64Hash= "& theBase64Hash &"<br/>");
</cfscript>
Demo of Differences:
<cfscript>
theEncoding = "UTF-16LE";
thePassword = "DT!#12";
base64Salt = "+muo6gAmjvvyy5doTdjyaA==";
// extract the bytes SEPARATELY
saltBytes = binaryDecode(base64Salt, "base64");
passBytes = charsetDecode(thePassword, theEncoding );
ArrayUtils = createObject("java", "org.apache.commons.lang.ArrayUtils");
separateBytes = ArrayUtils.addAll( saltBytes, passBytes );
// concatenate first, THEN extract the bytes
theSalt = charsetEncode( binaryDecode(base64Salt, "base64"), theEncoding );
concatenatedBytes = charsetDecode( theSalt & thePassword, theEncoding );
// these are the raw bytes BEFORE hashing
WriteOutput("separateBytes= "& arrayToList(separateBytes, "|") &"<br>");
WriteOutput("concatenatedBytes"& arrayToList(concatenatedBytes, "|") );
</cfscript>
Results:
separateBytes = -6|107|-88|-22|0|38|-114|-5|-14|-53|-105|104|77|-40|-14|104|68|0|84|0|33|0|64|0|49|0|50|0
concatenatedBytes = -6|107|-88|-22|0|38|-114|-5|-14|-53|-105|104|-3|-1|68|0|84|0|33|0|64|0|49|0|50|0
Most likely the password is not encrypted, it is hashed. Hashing is different from encrypting, because it is not reversible.
You would not use ColdFusion's encrypt() function for this, you would use its hash() function.
So the questions you'll need to answer to figure out how to hash the passwords in CF to be able to auth against the DNN users are:
What algorithm is DNN using to hash the passwords?
How is the salt being used with the password prior to hashing?
Is DNN iterating over the hash X number of times to improve security?
All of those questions must be answered to determine how CF must use the hash() function in combination with the salt and user-submitted passwords.
I'll make some assumptions to provide an answer.
If we assume that noiteration is being done and that the salt is simply being appended to the password prior to using SHA1 to hash the password, then you'd be able to reproduce the hash digest like this:
<cfset hashDigest = hash(FORM.usersubmittedPassword & saltFromDB, "SHA1") />
(Posting a new response to keep the "encrypted" process separate from "hashing")
For "encrypted" keys, the DNN side uses the standard algorithms ie DES, 3DES or AES - depending on your machineKey settings. But with a few differences you need to match in your CF code. Without knowing your actual settings, I will assume you are using the default 3DES for now.
Data To Encrypt
The encrypted value is a combination of the salt and password. But as with hashing, DNN uses UTF-16LE. Unfortunately, ColdFusion's Encrypt() function always assumes UTF-8, which will produce a very different result. So you need to use the EncryptBinary function instead.
// sample valus
plainPassword = "password12345";
base64Salt = "x7le6CBSEvsFeqklvLbMUw==";
hexDecryptKey = "303132333435363738393031323334353637383930313233";
// first extract the bytes of the salt and password
saltBytes = binaryDecode(base64Salt, "base64");
passBytes = charsetDecode(plainPassword, "UTF-16LE" );
// next combine the bytes. note, the returned arrays are immutable,
// so we cannot use the standard CF tricks to merge them
ArrayUtils = createObject("java", "org.apache.commons.lang.ArrayUtils");
dataBytes = ArrayUtils.addAll( saltBytes, passBytes );
Encryption Algorithm
With block ciphers, ColdFusion defaults to ECB mode. (See Strong Encryption in ColdFusion) Whereas .NET defaults to CBC mode, which requires an additional IV value. So you must adjust your CF code to match.
// convert DNN hex key to base64 for ColdFusion
base64Key = binaryEncode(binaryDecode( hexDecryptKey, "hex"), "base64");
// create an IV and intialize it with all zeroes
// block size: 16 => AES, 8=> DES or TripleDES
blockSize = 8;
iv = javacast("byte[]", listToArray(repeatString("0,", blocksize)));
// encrypt using CBC mode
bytes = encryptBinary(dataBytes, base64Key, "DESede/CBC/PKCS5Padding", iv);
// result: WBAnoV+7cLVI95LwVQhtysHb5/pjqVG35nP5Zdu7T/Cn94Sd8v1Vk9zpjQSFGSkv
WriteOutput("encrypted password="& binaryEncode( bytes, "base64" ));