Hi! can anyone tell me how to validate the sha2+salt password while log in? - hash

can anyone tell me how to validate the sha2+salt password while log in?? i am working in wicket framework and pg admin database, i was told to use hashing algorithm to create secure passwords. I just saw this example source code and i implemented it in my applciation and it just worked, but i dont know how to validate the salt+hash passwords while log in again. But i could able to validate the simple sha-2 paswwords but i couldn't and i don't know how to validate the sha2+salt password.
public class SHAExample {
public static void main(String[] args) throws NoSuchAlgorithmException {
String passwordToHash = "password";
String salt = getSalt();
String securePassword = get_SHA_1_SecurePassword(passwordToHash, salt);
System.out.println(securePassword);
securePassword = get_SHA_256_SecurePassword(passwordToHash, salt);
System.out.println(securePassword);
securePassword = get_SHA_384_SecurePassword(passwordToHash, salt);
System.out.println(securePassword);
securePassword = get_SHA_512_SecurePassword(passwordToHash, salt);
System.out.println(securePassword);
}
private static String get_SHA_1_SecurePassword(String passwordToHash, String salt)
{
String generatedPassword = null;
try {
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(salt.getBytes());
byte[] bytes = md.digest(passwordToHash.getBytes());
StringBuilder sb = new StringBuilder();
for(int i=0; i< bytes.length ;i++)
{
sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));
}
generatedPassword = sb.toString();
}
catch (NoSuchAlgorithmException e)
{
e.printStackTrace();
}
return generatedPassword;
}
//Add salt
private static String getSalt() throws NoSuchAlgorithmException
{
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
byte[] salt = new byte[16];
sr.nextBytes(salt);
return salt.toString();
}
}
Output:
e4c53afeaa7a08b1f27022abd443688c37981bc4

You have to do the same steps as you did when storing the password hash. That means you calculate the hash of the entered password with the same algorithm and the same salt you used before, then you can compare the hashes.
Be aware that the SHA* hash algorithms are not secure to hash passwords, because they are ways too fast and can be brute-forced too easily. Instead you switch to a slow key-derivation function like BCrypt or PBKDF2.

Related

How to encrypt data in one app and decrypt it in different Windows app with RSA keys tied to local system?

I have a setup where I need to encrypt blob of data in one app and decrypt it in different app.
I built a sample app that creates a named CngKey object. Then create a RSACng using CngKey object. Then use RSACng object to do encryption/decryption. What I found is that the key changes across restarts of the application even though it is loaded using the name it was created with. I am lost trying to understand the relation between CngKey and RSACng objects.
Below is snippet of code that describes what I am trying to do:
using System;
using System.IO;
using System.Security.Cryptography;
namespace TPMCrypto
{
class Program
{
static byte[] data = { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 };
static byte[] privateKey;
private static byte[] encrypted;
private static byte[] decrypted;
static void Main(string[] args)
{
const string MyKey = "MyRSAKey";
CngKey cngKey = null;
string cmd = args.Length > 0 ? args[0] : "";
try
{
CngKeyCreationParameters cng = new CngKeyCreationParameters
{
KeyUsage = CngKeyUsages.AllUsages,
KeyCreationOptions = CngKeyCreationOptions.MachineKey,
Provider = CngProvider.MicrosoftSoftwareKeyStorageProvider
};
if (!CngKey.Exists(MyKey, CngProvider.MicrosoftSoftwareKeyStorageProvider, CngKeyOpenOptions.MachineKey))
{
Console.WriteLine("Creating rsaKey");
cngKey = CngKey.Create(CngAlgorithm.Rsa, MyKey, cng);
}
else
{
Console.WriteLine("Opening rsaKey");
cngKey = CngKey.Open(MyKey, CngProvider.MicrosoftSoftwareKeyStorageProvider, CngKeyOpenOptions.MachineKey);
}
RSACng rsaKey = new RSACng(cngKey)
{
KeySize = 2048
};
privateKey = rsaKey.Key.Export(CngKeyBlobFormat.GenericPrivateBlob);
string prvResult = ByteArrayToHexString(privateKey, 0, privateKey.Length);
Console.WriteLine("\nPrivate key - length = " + privateKey.Length + "\n" + prvResult + "\n");
const string FILE_PATH = #"\temp\tpmtests\encryptedblob.dat";
// Encrypt / decrypt
if (cmd == "readfromfile")
{
Directory.CreateDirectory(Path.GetDirectoryName(FILE_PATH));
encrypted = File.ReadAllBytes(FILE_PATH);
}
else if (cmd == "deletekey")
{
cngKey.Delete();
return;
}
else
{
encrypted = Encrypt(rsaKey, data);
Console.WriteLine("The encrypted blob: ");
Console.WriteLine(ByteArrayToHexString(encrypted, 0, encrypted.Length));
File.WriteAllBytes(FILE_PATH, encrypted);
}
decrypted = Decrypt(rsaKey, encrypted);
bool result = ByteArrayCompare(data, decrypted);
if (result)
Console.WriteLine("Encrypt / decrypt works");
else
Console.WriteLine("Encrypt / decrypt fails");
}
catch (Exception e)
{
Console.WriteLine("Exception " + e.Message);
}
finally
{
if (cngKey != null)
cngKey.Dispose();
}
Console.ReadLine();
}
static bool ByteArrayCompare(byte[] a1, byte[] a2)
{
if (a1.Length != a2.Length)
return false;
for (int i = 0; i < a1.Length; i++)
if (a1[i] != a2[i])
return false;
return true;
}
public static string ByteArrayToHexString(byte[] bytes, int start, int length)
{
string delimitedStringValue = BitConverter.ToString(bytes, start, length);
return delimitedStringValue.Replace("-", "");
}
public static byte[] Sign512(byte[] data, byte[] privateKey)
{
CngKey key = CngKey.Import(privateKey, CngKeyBlobFormat.GenericPrivateBlob);
RSACng crypto = new RSACng(key);
return crypto.SignData(data, HashAlgorithmName.SHA512, RSASignaturePadding.Pkcs1);
}
public static bool VerifySignature512(byte[] data, byte[] signature, byte[] publicKey)
{
CngKey key = CngKey.Import(publicKey, CngKeyBlobFormat.GenericPublicBlob);
RSACng crypto = new RSACng(key);
return crypto.VerifyData(data, signature, HashAlgorithmName.SHA512, RSASignaturePadding.Pkcs1);
}
public static byte[] Encrypt(byte[] publicKey, byte[] data)
{
CngKey key = CngKey.Import(publicKey, CngKeyBlobFormat.GenericPublicBlob);
RSACng crypto = new RSACng(key);
var result = Encrypt(crypto, data);
return result;
}
public static byte[] Encrypt(RSACng crypto, byte[] data)
{
if (null == crypto)
return null;
var result = crypto.Encrypt(data, RSAEncryptionPadding.OaepSHA512);
return result;
}
public static byte[] Decrypt(byte[] privateKey, byte[] data)
{
CngKey key = CngKey.Import(privateKey, CngKeyBlobFormat.GenericPrivateBlob);
RSACng crypto = new RSACng(key);
var result = Decrypt(crypto, data);
return result;
}
public static byte[] Decrypt(RSACng aKey, byte[] data)
{
if (null == aKey)
return null;
var result = aKey.Decrypt(data, RSAEncryptionPadding.OaepSHA512);
return result;
}
}
}
I am aware of dpapi and how to do this using it. I don't want to use it for this, please don't point me in that direction. I am using CNG flavor of crypto to force C# use NCryptXYZ crypto calls and the desire is to secure the keys in TPM.
Ah, looking at your code again, you've made a goof.
RSACng rsaKey = new RSACng(cngKey)
{
KeySize = 2048
};
Setting the KeySize property on an RSACng does one of two things:
If get_KeySize == value, ignore the input, do nothing.
Else, detach from the current key and the next time the key is used, generate a new key of get_KeySize at the time.
So you're opening an existing key, then discarding it, and generating a new ephemeral key. (Which you could see by checking rsaKey.Key.Name, it won't match your input).
Presumably you did this as a way to create the key with the right size in the first place, but you're too late. The correct way is
CngKeyCreationParameters cng = new CngKeyCreationParameters
{
KeyUsage = CngKeyUsages.AllUsages,
KeyCreationOptions = CngKeyCreationOptions.MachineKey,
Provider = CngProvider.MicrosoftSoftwareKeyStorageProvider,
Parameters =
{
new CngProperty("Length", BitConverter.GetBytes(2048), CngPropertyOptions.Persist),
},
};

How to convert encrypt java code below in flutter

I m requirement is to convert below java encrypt code to flutter as i need to encrypt few fields value before sending to api.
Below is java encrypt code which i need to convert to java
public static String encrypt(String text, String algo, Key key) {
byte[] cipherText;
String output;
try {
if("RSA".equals(algo)) {
throw new IllegalArgumentException("Do not pass just algo pass with padding and blocking stuff!");
}
if(BuildConfig.DEBUG) {
Log.d(TAG, "encrypt in: "+text);
Log.d(TAG, "algo: "+algo);
Log.d(TAG, "key: "+key);
}
final Cipher cipher = Cipher.getInstance(algo);
if(algo.contains("AES")) {
AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivBytes);
cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
} else {
cipher.init(Cipher.ENCRYPT_MODE, key);
}
cipherText = cipher.doFinal(text.getBytes(StandardCharsets.UTF_8));
output = new String(Base64.encode(cipherText));
if(BuildConfig.DEBUG) {
Log.d(TAG, "encrypt out: "+output);
}
return output;
} catch (Exception e) {
Log.e(TAG, SDKConstants.STRING_ERROR + e, e);
return null;
}
}
char[] encPwd = Objects.requireNonNull(CryptoHelper.encrypt(Objects.requireNonNull(binding.textIPassword.getEditText()).getText().toString(), CryptoHelper.ALGO_FOR_RSA, key)).toCharArray();
Please help me in converting above java code to flutter as i need to encrypt one field before sending it to api call.
Any help is appreciated!
Just work through the Java line by line and figure out Dart equivalents. Use the other linked question as your guide. This should work (if I guessed the cipher correctly):
import 'package:pointycastle/export.dart';
String encrypt(String plainText, RSAPublicKey public) {
final plainBytes = utf8.encode(plainText) as Uint8List;
final cipher = PKCS1Encoding(RSAEngine())
..init(true, PublicKeyParameter<RSAPublicKey>(public));
final cipherBytes = cipher.process(plainBytes);
return base64Encode(cipherBytes);
}

Flutter AES128 encryption not matching with java and angular AES encryption

I have to implement a dart algorithm in order to encrypt a password and send it to a server for authentication from a flutter app (it's barely a week since I'm on flutter/dart). This has already been implemented in an android app and angular web app (not from me), which both produce the same encrypted password even though with different algorithms.
Java code for android:
import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.CryptoPrimitive;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import org.bouncycastle.util.encoders.Base64;
import org.bouncycastle.util.encoders.Hex;
public class AesUtil {
private final int keySize;
private final int iterationCount;
private final Cipher cipher;
public AesUtil(int keySize, int iterationCount) {
this.keySize = keySize;
this.iterationCount = iterationCount;
try {
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
throw fail(e);
}
}
public String decrypt(String salt, String iv, String passphrase, String ciphertext) {
try {
SecretKey key = generateKey(salt, passphrase);
byte[] decrypted = doFinal(Cipher.DECRYPT_MODE, key, iv, base64(ciphertext));
return new String(decrypted, "UTF-8");
} catch (UnsupportedEncodingException e) {
return null;
} catch (Exception e) {
return null;
}
}
private byte[] doFinal(int encryptMode, SecretKey key, String iv, byte[] bytes) {
try {
cipher.init(encryptMode, key, new IvParameterSpec(hex(iv)));
return cipher.doFinal(bytes);
} catch (InvalidKeyException
| InvalidAlgorithmParameterException
| IllegalBlockSizeException
| BadPaddingException e) {
return null;
}
}
private SecretKey generateKey(String salt, String passphrase) {
try {
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(passphrase.toCharArray(), hex(salt), iterationCount, keySize);
SecretKey key = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES");
return key;
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
return null;
}
}
public static byte[] base64(String str) {
return Base64.decode(str);
}
public static String base64(byte[] bytes) {
return new String(Base64.encode(bytes));
}
public static byte[] hex(String str) {
try {
return Hex.decode(str);
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
public static String hex(byte[] bytes) {
return Hex.encode(bytes).toString();
}
private IllegalStateException fail(Exception e) {
return null;
}
public String random(int length) {
byte[] salt = new byte[length];
new SecureRandom().nextBytes(salt);
return hex(salt);
}
public String encrypt(String salt, String iv, String passphrase, String plaintext) {
try {
SecretKey key = generateKey(salt, passphrase);
byte[] encrypted = doFinal(Cipher.ENCRYPT_MODE, key, iv, plaintext.getBytes("UTF-8"));
return base64(encrypted);
} catch (UnsupportedEncodingException e) {
throw fail(e);
}
}
public String encriptToAES(String password) {
//`
//for some reasons key, iv and salt are hardcoded string
//
final String key = "hardcoded_key_16_characters";
final String iv = "hardcoded_iv_32_characters";
final String salt = "hardcoded_salt_32_characters";
String ciphertext = encrypt(salt, iv, key, password);
String preEncr = new String(Base64.encode((iv + "::" + salt + "::" + ciphertext).getBytes()));
return preEncr;
}
}
And this is the java line of code which generate the encrypted password:
AesUtil(128, 1000).encriptToAES(password)
JS code for angular:
import * as CryptoJS from 'crypto-js';
export class AesUtil{
private keySize;
private iterationCount;
constructor(keySize, iterationCount) {
this.keySize = keySize / 32;
this.iterationCount = iterationCount;
};
generateKey(salt, passPhrase) {
var key = CryptoJS.PBKDF2(
passPhrase,
CryptoJS.enc.Hex.parse(salt),
{ keySize: this.keySize, iterations: this.iterationCount });
return key;
}
encrypt(salt, iv, passPhrase, plainText) {
var key = this.generateKey(salt, passPhrase);
var encrypted = CryptoJS.AES.encrypt(
plainText,
key,
{ iv: CryptoJS.enc.Hex.parse(iv) });
return encrypted.ciphertext.toString(CryptoJS.enc.Base64);
}
decrypt(salt, iv, passPhrase, cipherText) {
var key = this.generateKey(salt, passPhrase);
var cipherParams = CryptoJS.lib.CipherParams.create({
ciphertext: CryptoJS.enc.Base64.parse(cipherText)
});
var decrypted = CryptoJS.AES.decrypt(
cipherParams,
key,
{ iv: CryptoJS.enc.Hex.parse(iv) });
return decrypted.toString(CryptoJS.enc.Utf8);
}
}
And this code does the trick:
const iv = CryptoJS.lib.WordArray.random(128/8).toString(CryptoJS.enc.Hex);
const salt = CryptoJS.lib.WordArray.random(128/8).toString(CryptoJS.enc.Hex);
const aesUtil = newAesUtil(128,1000);
const cipherText = aesUtils.encrypt(salt,iv,'hardcoded_key_16_characters',password);
const aesPassword = (iv+ '::' + salt + '::'+ cipherText);
const encryptedPassword = btoa(aesPassword);
For what I can understand I need an AES128 encryption method, where to set a specific number of iterations, which accepts iv and salt and eventually encrypt the result with Base64.
I have already tried all kinds of dart encryption packages on pub.dev and snippets without success.
I was relying on this one in particular, but even with hardcoded parameters the result password doesn't match and I'm not able to figure out why. Does anyone know on which elements I have to focus in order to achieve the same result in flutter? For example, which aes128 'plugin' should I use? Static or random iv and salt? All kind of things, I'm pretty much lost. Thanks
UPDATE:
import 'dart:typed_data';
import 'dart:convert';
import 'package:cryptography/cryptography.dart';
final password = "justatest";
final key = "0123456789abcdef";
final iv = "0123456789abcdefghijklmnopqrstuv";
final salt = "abcdefghijklmnopqrstuvwzyz012345";
encryptAESCryptoJS() {
final pbkdf2 = Pbkdf2(
macAlgorithm: Hmac(sha1),
iterations: 1000,
bits: 128,
);
final Uint8List hashBytes = pbkdf2.deriveBitsSync(
utf8.encode(key),
nonce: Nonce(utf8.encode(salt)),
);
}

AES Encryption and decryption using jks file

I have one small doubt as i am new to AES.
I encrypted a string using one certificate with some password lets say , 'xxx'.
Now i duplicated the certificate by changing the password of it.
When i try to decrypt the encrypted string with the duplicated cert, it says Bad padding exception.Exception in thread "main" javax.crypto.BadPaddingException: Given final block not properly padded
However, when i use the original cert, it decrypts properly.
Could anyone please guide me on it?
public SecretKey retrieveKey(String password, byte[] certFile) throws Exception {
try {
String alias = null;
certPass = password;
char[] pass = certPass.toCharArray();
KeyStore keyStore = KeyStore.getInstance("jceks");
InputStream inputStream = new ByteArrayInputStream(certFile);
keyStore.load(inputStream, pass);
Enumeration enumeration = keyStore.aliases();
while (enumeration.hasMoreElements()) {
alias = (String) enumeration.nextElement();
}
Certificate cert = keyStore.getCertificate(alias);
Key key = cert.getPublicKey();
aesSecretKey = new SecretKeySpec(key.getEncoded(), algorithm);
byte[] encoded = aesSecretKey.getEncoded();
byte[] encryptionKey = Arrays.copyOfRange(encoded, encoded.length - 16, encoded.length);
aesSecretKey = new SecretKeySpec(encryptionKey, algorithm);
} catch (IOException e) {
throw e;
} catch (Exception e) {
throw e;
}
return aesSecretKey;
}
You should use RSA to wrap / unwrap the AES key. The public key is not identical to the AES key, so the following code is certainly incorrect:
Key key = cert.getPublicKey();
aesSecretKey = new SecretKeySpec(key.getEncoded(), algorithm);

Iphone push notification issue

I am working on iphone push notification. I can able to get my device token. I am using .net for pushing json data. But the issue is i cant get the notification. I just want to know whether .net has to push json data over in hosted machine?
Regards,
sathish
I believe that is related to:
Add iPhone push notification using ASP.NET server
Read through the linked project in there. It is pretty comprehensive. You can actually just use that library... it is pretty good.
Unless I misunderstood the question?
Use following snippet to send Push Notification
public void PendingNotification(string DeviceToken,string message)
{
try
{
int port = 2195;
//Developer
String hostname = "gateway.sandbox.push.apple.com";
//Production
//String hostname = "gateway.push.apple.com";
String certificatePassword = "XXXXXXX";
string certificatePath = Server.MapPath("~/cer.p12");
TcpClient client = new TcpClient(hostname, port);
X509Certificate2 clientCertificate = new X509Certificate2(System.IO.File.ReadAllBytes(certificatePath), certificatePassword);
X509Certificate2Collection certificatesCollection = new X509Certificate2Collection(clientCertificate);
SslStream sslStream = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
sslStream.AuthenticateAsClient(hostname, certificatesCollection, SslProtocols.Tls, false);
//String DeviceToken = "XXXXXXXXXXXX";
String LoginName = "Name";
int Counter = 1; //Badge Count;
String Message = message;
String UID = "your choice UID";
string payload = "{\"aps\":{\"alert\":\"" + Message + "\",\"badge\":" + Counter + ",\"sound\":\"default\"},\"UID\":\"" + UID + "\",\"LoginName\":\"" + LoginName + "\"}";
MemoryStream memoryStream = new MemoryStream();
BinaryWriter writer = new BinaryWriter(memoryStream);
writer.Write((byte)0);
writer.Write((byte)0);
writer.Write((byte)32);
writer.Write(HexStringToByteArray(DeviceToken.ToUpper()));
writer.Write((byte)0);
writer.Write((byte)payload.Length);
byte[] b1 = System.Text.Encoding.UTF8.GetBytes(payload);
writer.Write(b1);
writer.Flush();
byte[] array = memoryStream.ToArray();
sslStream.Write(array);
}
catch (Exception ex)
{
//Response.Write(ex.Message);
}
}
public static byte[] HexStringToByteArray(string hex)
{
return Enumerable.Range(0, hex.Length)
.Where(x => x % 2 == 0)
.Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
.ToArray();
}
public static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
if (sslPolicyErrors == SslPolicyErrors.None)
return true;
Console.WriteLine("Certificate error: {0}", sslPolicyErrors);
return false;
}