hi i m creating PayUMoney Payment Gateway and i m sending parametrs to c# code..then test site is open..after entring test card no,CVV,test Name my transaction process start but after that my transaction is failed..i dont know how it is?? please help me to solve my problem.
enter code here
public string Generatehash512(string text) //this is Hash generate method
{
byte[] message = Encoding.UTF8.GetBytes(text);
UnicodeEncoding UE = new UnicodeEncoding();
byte[] hashValue;
SHA512Managed hashString = new SHA512Managed();
string hex = "";
hashValue = hashString.ComputeHash(message);
foreach (byte x in hashValue)
{
hex += String.Format("{0:x2}", x);
}
return hex;
}
if (!string.IsNullOrEmpty(hash1)) //all parameter that i sent.
{
hash.Value = hash1;
txnid.Value = txnid1;
System.Collections.Hashtable data = new
System.Collections.Hashtable(); // adding values in gash table for data post
data.Add("hash", hash.Value);
data.Add("key", key.Value);
data.Add("txnid", txnid.Value);
string AmountForm =
Convert.ToDecimal(amount.Text.Trim()).ToString("g29");// eliminating trailing zeros
amount.Text = AmountForm;
data.Add("amount", amount.Text.Trim());
data.Add("firstname", firstname.Text.Trim());
data.Add("email", email.Text.Trim());
data.Add("phone", phone.Text.Trim());
data.Add("productinfo", productinfo.Text.Trim());
data.Add("surl", surl.Text.Trim());
data.Add("furl", furl.Text.Trim());
data.Add("lastname", lastname.Text.Trim());
data.Add("curl", curl.Text.Trim());
data.Add("address1", address1.Text.Trim());
data.Add("address2", address2.Text.Trim());
data.Add("city", city.Text.Trim());
data.Add("state", state.Text.Trim());
data.Add("country", country.Text.Trim());
data.Add("zipcode", zipcode.Text.Trim());
data.Add("udf1", udf1.Text.Trim());
data.Add("udf2", udf2.Text.Trim());
data.Add("udf3", udf3.Text.Trim());
data.Add("udf4", udf4.Text.Trim());
data.Add("udf5", udf5.Text.Trim());
data.Add("pg", pg.Text.Trim());
data.Add("service_provider", service_provider.Text.Trim());
data.Add("abc", hash_string);
string strForm = PreparePOSTForm(action1, data);
Page.Controls.Add(new LiteralControl(strForm));
}
Related
I’m encrypting sensitive data using the C# AES class, Aes.Create() method before saving to an SQLite DB. My base round trip is:
*Saving/retrieving each Byte[ ] without converting threw “The specified key is not a valid size for this algorithm.” when decrypting.
The process leverages the MSDN example and is working well:
I’m concerned, however, that cipher, key & IV values must all be stored/retrieved together and am attempting to disguise the values stored in the DB. I’ve tried three procedures to disguise/revert the relevant string values. Unfortunately adding a disguise/revert procedure throws the following error when decrypting:
System.Security.Cryptography.CryptographicException
HResult=0x80131430 Message=Padding is invalid and cannot be removed.
Source=System.Core
I've tried:
switching from Aes.Create to AesManaged; result: no change
setting Padding = PaddingMode.None; result: threw "'System.Security.Cryptography.CryptographicException' occurred in mscorlib.dll 'Length of the data to encrypt is invalid.'"
setting Padding = PaddingMode.Zeros; result: ran with no error but round trips returned incorrect & unreadable values (see image):
A number of posts (of the many, most of the issues are base process round trip failures) in this forum regarding this error state that the Padding error can be thrown for a variety of reasons only one of which is actually a Padding error. One post ( Padding is invalid and cannot be removed?, 4th reply sorted by Trending) states:
If the same key and initialization vector are used for encoding and
decoding, this issue does not come from data decoding but from data
encoding.
Since my keys & IVs are the same this looked hopeful. However, as the above image implies if I'm interpreting it correctly, changing encoding doesn't seem to help.
Since my base processs by itself works I suspect my case fall into the "not really a Padding error" category.
The disguise/revert procedures
First procedure
Remove the “=” character(s) at the end of each string since it’s a blatant indicator of “something important”
Split cipher, key & IV strings based on a random number into two halves
Swap the two halves’ positions and insert unique random text of random length between the halves
Create a random length “reversion code” capturing randomized split indices and resultant string lengths
Second procedure: same as the first but leave “=” character(s) intact.
Third procedure
Split the random text of three different random length strings
“Wrap” them around the cipher, key & IV strings
Create the “reversion code”
For all three procedures: upon retrieval from the DB reverse the process using the “reversion code”. In the third procedure the original strings should, theoretically, be “untouched”.
In all three cases output indicates Original and Reverted are identical (single run testing output sample):
The disguise/revert code
Code for the third procedure since it probably has the greatest probability of working. The Encrypt & Decrypt methods are included in case they're relevant:
private static string _cipherText = "", _keyText = "", _vectorText = "";
// Prior to saving: third procedure
public static void SaveSensitivePrep(string input, bool parent)
{
input = "secretID";
Console.WriteLine($"\nOriginal: {input}");
string startString = default, extractor = default;
int disguiseLen = 0, startStringLen = 0, doneStringLen = 0;
for (int i = 0; i < 3; i++)
{
using (Aes toEncrypt = Aes.Create())
{
byte[] cypherBytes = Encrypt(input, toEncrypt.Key, toEncrypt.IV);
string cipherText = Convert.ToBase64String(cypherBytes);
string keyText = Convert.ToBase64String(toEncrypt.Key);
string vectorText = Convert.ToBase64String(toEncrypt.IV);
if (i == 0) _cipherText = startString = cipherText;
else if (i == 1) _keyText = startString = keyText;
else if (i == 2) _vectorText = startString = vectorText;
int disguiseSelector = new Random().Next(101);
string disguiseTxt = default;
List<Disguises> disguise_DB = DBconnect.Disguises_Load();
for (int c = 0; c < disguise_DB.Count; c++)
{
if (c == disguiseSelector) { disguiseTxt = disguise_DB[c].Linkages; break; }
}
disguiseLen = disguiseTxt.Length;
int disguiseSplitIndex = new Random().Next(10, 22);
string startTxt = disguiseTxt.Substring(0, disguiseSplitIndex);
string endTxt = disguiseTxt.Substring(disguiseSplitIndex);
string doneString = $"{startTxt}{startString}{endTxt}";
doneStringLen = doneString.Length;
extractor = $"{disguiseSplitIndex}{disguiseLen}{startStringLen}" +
$"{disguiseSelector + new Random().Next(5000000)}";
if (i == 0) DBconnect.Encrypted_Update_CT(Host, extractor, doneString);
else if (i == 1) DBconnect.Encrypted_Update_CK(Host, extractor, doneString);
else if (i == 2) DBconnect.Encrypted_Update_CV(Host, extractor, doneString);
}
}
}
// After retrieval: third procedure
public static string LoadSensitive(string input, bool parent)
{
string cipherText = "", keyText = "", vectorText = "";
for (int i = 0; i < 3; i++)
{
string extractor = "";
int disguiseLeft, disguiseRight;
List<EncryptedClass> host = DBconnect.Encrypted_Load(Host);
string doneString = "";
if (i == 0) { extractor = host[0].RCC; doneString = host[0].cipherText; }
else if (i == 1) { extractor = host[0].RCK; doneString = host[0].keyText; }
else if (i == 2) { extractor = host[0].RCV; doneString = host[0].vectorText; }
string disguiseSplitter = extractor.Substring(0, 2);
string disguiseLen_t = extractor.Substring(2, 2);
string startStringLen_t = extractor.Substring(4, 2);
int.TryParse(disguiseSplitter, out int indx);
int.TryParse(disguiseLen_t, out int disguiseLen);
int.TryParse(startStringLen_t, out int startStringLen);
disguiseRight = disguiseLen - indx;
disguiseLeft = disguiseLen - disguiseRight;
string e_extrctd = doneString.Substring(disguiseLeft, startStringLen);
if (i == 0) cipherTxt = revertedString;
else if (i == 1) keyTxt = revertedString;
else vectorTxt = revertedString;
}
byte[] cypher = Convert.FromBase64String(cipherText);
byte[] key = Convert.FromBase64String(keyText);
byte[] vector = Convert.FromBase64String(vectorText);
return Decrypt(cypher, key, vector);
}
static byte[] Encrypt(string input, byte[] key, byte[] iv)
{
// NULL/Length > 0 checks.
byte[] encrypted;
using (Aes input_e = Aes.Create())
{
input_e.Key = key;
input_e.IV = iv;
ICryptoTransform ict = input_e.CreateEncryptor(input_e.Key, input_e.IV);
using (MemoryStream msInput = new MemoryStream())
{
using (CryptoStream csInput = new CryptoStream(msInput, ict, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csInput))
{
swEncrypt.Write(input);
}
encrypted = msInput.ToArray();
}
}
}
return encrypted;
}
static string Decrypt(byte[] cipherText, byte[] keyText, byte[] vectorText)
{
// NULL/Length > 0 checks.
string roundtrip = null;
using (Aes output_e = Aes.Create())
{
output_e.Key = keyText;
output_e.IV = vectorText;
ICryptoTransform ict = output_e.CreateDecryptor(output_e.Key, output_e.IV);
using (MemoryStream msOutput = new MemoryStream(cipherText))
{
using (CryptoStream csOutput = new CryptoStream(msOutput, ict, CryptoStreamMode.Read))
{
using (StreamReader srOutput = new StreamReader(csOutput))
{
roundtrip = srOutput.ReadToEnd();
}
}
}
}
return roundtrip;
}
Any guidance on how/why the disguise/revert is getting deformed will be appreciated.
EDIT: scope clarification: the security functionality in this instance is for a Winforms/SQLite app which has an FTP component (WinSCP). The app's high level objective is a desktop tool streamlining TLS/SSL Certificate request/issuance via Let's Encrypt. The primary security objective is protecting FTP session credentials should an unauthorized & semi-knowledgeable person gain access to the DB. The secondary security objective is to keep it as simple as possible.
I have to rewrite this php code to c#
$sign_params = ['name'=>"John", 'age'=>18];
$client_secret = 'test secret key';
ksort($sign_params); // Sort array by keys
$sign_params_query = http_build_query($sign_params); // Forming string like "param_name1=value¶m_name2=value"
$sign = rtrim(strtr(base64_encode(hash_hmac('sha256', $sign_params_query, $client_secret, true)), '+/', '-_'), '='); // get hash code
return $sign;
Here what I try:
public class apiHelper : MonoBehaviour
{
const string client_secret = "test secret key";
public static string checkSign(Dictionary<string, dynamic> fields)
{
//* sort by keys
var list = fields.Keys.ToList();
list.Sort();
string sign_params_query = "";
//* forming string like "param_name1=value¶m_name2=value"
foreach (var key in list)
{
sign_params_query = sign_params_query + key + "=" + fields[key];
if (key != list.Last()) sign_params_query = sign_params_query + "&";
}
//* get hash code
string sign = System.Convert.ToBase64String(GetHash(sign_params_query, client_secret));
char[] charsToTrim = { '=' };
return sign.Replace("+", "-").TrimEnd(charsToTrim);
}
static byte[] GetHash(string url, string key)
{
using (HMACSHA256 hmac = new HMACSHA256(Encoding.ASCII.GetBytes(key)))
{
byte[] data = hmac.ComputeHash(Encoding.UTF8.GetBytes(url));
return data;
}
}
}
Well, finally I get different hash than in php example ._. What did I wrong? Its my 1st time with cryptho or smth like that
Well, problem wath with strings which have special chars. I have to use url_encode c# equivalent to solve it.
I'm currently trying to figure out how to calculate the MD5 message digest for message attributes in AWS.
I'm following the uri SQS message metadata > Calculating the MD5 message digest for message attributes
Although this seems straight forward I'm trying to get the hash of the following attribute
var messageAttributes = new Dictionary<string, MessageAttributeValue>
{
{"UserName", new MessageAttributeValue {DataType ="String", StringValue = "Me"}}
};
I've sent this message and the MD5 response was 3a6071d47534e3e07414fea5046fc217
Trying to figure out the documentation I thought this should have done the trick:
private void CustomCalc()
{
var verifyMessageAttributes = new List<byte>();
verifyMessageAttributes.AddRange(EncodeString("UserName"));
verifyMessageAttributes.AddRange(EncodeString("String"));
verifyMessageAttributes.AddRange(EncodeString("Me"));
var verifyMessageAttributesMd5 = GetMd5Hash(verifyMessageAttributes.ToArray());
}
private List<byte> EncodeString(string data)
{
var result = new List<byte>();
if (BitConverter.IsLittleEndian)
{
result.AddRange(BitConverter.GetBytes(data.Length).Reverse());
}
else
{
result.AddRange(BitConverter.GetBytes(data.Length));
}
result.AddRange(Encoding.UTF8.GetBytes(data));
return result;
}
public static string GetMd5Hash(byte[] input)
{
using (var md5Hash = MD5.Create())
{
// Convert the input string to a byte array and compute the hash.
var dataBytes = md5Hash.ComputeHash(input);
// Create a new string builder to collect the bytes and create a string.
var sBuilder = new StringBuilder();
// Loop through each byte of the hashed data and format each one as a hexadecimal string.
foreach (var dataByte in dataBytes)
{
sBuilder.Append(dataByte.ToString("x2"));
}
// Return the hexadecimal string.
return sBuilder.ToString();
}
}
But I ended up with this cf886cdabbe5576c0ca9dc51871d10ae
Does anyone knows where I'm going wrong. It can't be that hard I guess I just don't see it at the moment.
You are almost there but missing one step:
Encode the transport type (String or Binary) of the value (1 byte).
Note The logical data types String and Number use the String transport
type.
The logical data type Binary uses the Binary transport type.
For the String transport type, encode 1.
For the Binary transport type, encode 2.
So you need to append either 1 or 2 before value, to indicate transport type. In your case:
var verifyMessageAttributes = new List<byte>();
verifyMessageAttributes.AddRange(EncodeString("UserName"));
verifyMessageAttributes.AddRange(EncodeString("String"));
verifyMessageAttributes.Add(1); // < here
verifyMessageAttributes.AddRange(EncodeString("Me"));
var verifyMessageAttributesMd5 = GetMd5Hash(verifyMessageAttributes.ToArray());
Here is stand-alone solution in Node.js:
const md5 = require('md5');
const SIZE_LENGTH = 4;
const TRANSPORT_FOR_TYPE_STRING_OR_NUMBER = 1;
const transportType1 = ['String', 'Number'];
module.exports = (messageAttributes) => {
const buffers = [];
const keys = Object.keys(messageAttributes).sort();
keys.forEach((key) => {
const { DataType, StringValue } = messageAttributes[key];
const nameSize = Buffer.alloc(SIZE_LENGTH);
nameSize.writeUInt32BE(key.length);
const name = Buffer.alloc(key.length);
name.write(key);
const typeSize = Buffer.alloc(SIZE_LENGTH);
typeSize.writeUInt32BE(DataType.length);
const type = Buffer.alloc(DataType.length);
type.write(DataType);
const transport = Buffer.alloc(1);
let valueSize;
let value;
if (transportType1.includes(DataType)) {
transport.writeUInt8(TRANSPORT_FOR_TYPE_STRING_OR_NUMBER);
valueSize = Buffer.alloc(SIZE_LENGTH);
valueSize.writeUInt32BE(StringValue.length);
value = Buffer.alloc(StringValue.length);
value.write(StringValue);
} else {
throw new Error(
'Not implemented: MessageAttributes with type Binary are not supported at the moment.'
);
}
const buffer = Buffer.concat([nameSize, name, typeSize, type, transport, valueSize, value]);
buffers.push(buffer);
});
return md5(Buffer.concat(buffers));
};
See more in the sqslite repo on GitHub
i have a method that i need to remake in C# based on this python code.
def _generateHash(self, password, time_stamp, nonce):
import hashlib
shaPw = hashlib.sha1()
shaPw.update( password )
m = hashlib.sha1()
m.update(str(time_stamp))
m.update(nonce)
m.update(shaPw.hexdigest())
m.update(self.api_key_secret)
return m.hexdigest()
hashing in C# is allot different compared to python. also my hashing experience is not that great. is there anybody that can help me?
this is wat i have right now.
private string GenerateHash(string password, double timeStamp, string nonce)
{
using (SHA1Managed sha1 = new SHA1Managed())
{
var pwHash = sha1.ComputeHash(Encoding.UTF8.GetBytes(password));
using (SHA1Managed sha1total = new SHA1Managed())
{
sha1total.ComputeHash(Encoding.UTF8.GetBytes(timeStamp.ToString()));
sha1total.ComputeHash(Encoding.UTF8.GetBytes(nonce));
string hexaHashPW = "";
foreach (byte b in pwHash)
{
hexaHashPW += String.Format("{0:x2}", b);
}
sha1total.ComputeHash(Encoding.UTF8.GetBytes(hexaHashPW));
sha1total.ComputeHash(Encoding.UTF8.GetBytes(_SecretApiKey));
var hmac = new HMACSHA1();
//string hexaHashTotal = "";
//foreach (byte b in sha1total.Hash)
//{
// hexaHashTotal += String.Format("{0:x2}", b);
//}
hmac.ComputeHash(sha1total.Hash);
var hexaHashTotal = hmac.Hash;
var endhash = BitConverter.ToString(hexaHashTotal).Replace("-", "");
return endhash;
}
}
}
after even more research and trail and error i found the way to produce the same hash as the python code.
this is the answer for others that have problems with this.
private string GenerateHash(string password, double timeStamp, string nonce)
{
using (SHA1Managed sha1 = new SHA1Managed())
{
var pwHash = sha1.ComputeHash(Encoding.UTF8.GetBytes(password));
using (SHA1Managed sha1total = new SHA1Managed())
{
string hexaHashPW = "";
foreach (byte b in pwHash)
{
hexaHashPW += String.Format("{0:x2}", b);
}
var hmacPW = new HMACSHA1();
hmacPW.ComputeHash(pwHash);
sha1total.ComputeHash(Encoding.UTF8.GetBytes(timeStamp.ToString() + nonce + hexaHashPW + _SecretApiKey));
var hmac = new HMACSHA1();
string hexaHashTotal = "";
foreach (byte b in sha1total.Hash)
{
hexaHashTotal += String.Format("{0:x2}", b);
}
hmac.ComputeHash(sha1total.Hash);
return hexaHashTotal.ToLower();
}
}
}
I'm trying to convert a java based code to c# as followed;
The original java code;
String str2 = "5f1fa09364a6ae7e35a090b434f182652ab8dd76:{\"expiration\": 1353759442.0991001, \"channel\": \"dreamhacksc2\", \"user_agent\": \".*"
Mac localMac = Mac.getInstance("HmacSHA1");
localMac.init(new SecretKeySpec("Wd75Yj9sS26Lmhve".getBytes(), localMac.getAlgorithm()));
String str3 = new BigInteger(1, localMac.doFinal(str2.getBytes())).toString(16);
Object[] arrayOfObject2 = new Object[2];
arrayOfObject2[0] = str3;
arrayOfObject2[1] = URLEncoder.encode(str2);
String str4 = String.format("%s:%s", arrayOfObject2);
And here is my WinRT based c# code
var token="5f1fa09364a6ae7e35a090b434f182652ab8dd76:{\"expiration\": 1353759442.0991001, \"channel\": \"dreamhacksc2\", \"user_agent\": \".*";
var encoding = new System.Text.UTF8Encoding();
var key = encoding.GetBytes("Wd75Yj9sS26Lmhve");
//var key = Convert.FromBase64String("Wd75Yj9sS26Lmhve");
var tokenData = encoding.GetBytes(token);
var result = HmacSha1(key, tokenData);
var hexString = new BigInteger(result).ToString("x");
var urlEncoded = System.Net.WebUtility.UrlEncode(token);
var combined = String.Format("{0}:{1}", hexString, urlEncoded);
and the hmacsha1 function as I'm running on WinRT;
public static byte[] HmacSha1(byte[] key, byte[] data)
{
var crypt = Windows.Security.Cryptography.Core.MacAlgorithmProvider.OpenAlgorithm("HMAC_SHA1");
var keyBuffer = Windows.Security.Cryptography.CryptographicBuffer.CreateFromByteArray(key);
var cryptKey = crypt.CreateKey(keyBuffer);
var dataBuffer = Windows.Security.Cryptography.CryptographicBuffer.CreateFromByteArray(data);
var signBuffer = Windows.Security.Cryptography.Core.CryptographicEngine.Sign(cryptKey, dataBuffer);
byte[] result;
Windows.Security.Cryptography.CryptographicBuffer.CopyToByteArray(signBuffer, out result);
return result;
}
So here's the corresponding outpus;
(JAVA) 92e893efe72a2f7df6ed409ce35819faba191a63:5f1fa09364a6ae7e35a090b434f182652ab8dd76%3A%7B%22expiration%22%3A+1353759442.0991001%2C+%22channel%22%3A+%22dreamhacksc2%22%2C+%22user_agent%22%3A+%22.*
(C#) 63b10e1d8e9f99cd7fba2ed46fe8e4a4a40222f5:5f1fa09364a6ae7e35a090b434f182652ab8dd76%3A%7B%22expiration%22%3A+1353759442.0991001%2C+%22channel%22%3A+%22dreamhacksc2%22%2C+%22user_agent%22%3A+%22.*
as shown above, the ouputs of HMAC_SHA1 from java and c# are not equal. Any ideas? Am I running encoding problems?
Just keep it simple and the code equal.
Java:
public static String toHexString(byte[] bytes) {
StringBuilder sb = new StringBuilder(bytes.length * 2);
for (int i = 0; i < bytes.length; ++i) {
sb.append(String.format("%02x", bytes[i]));
}
return sb.toString();
}
public static void main(String[] args) {
String str2 = "5f1fa09364a6ae7e35a090b434f182652ab8dd76:{\"expiration\": 1353759442.0991001, \"channel\": \"dreamhacksc2\", \"user_agent\": \".*";
Mac localMac;
try {
localMac = Mac.getInstance("HmacSHA1");
localMac.init(new SecretKeySpec("Wd75Yj9sS26Lmhve"
.getBytes("UTF-8"), localMac.getAlgorithm()));
byte[] result = localMac.doFinal(str2.getBytes("UTF-8"));
String hexString = toHexString(result);
System.out.println(hexString);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
Result:
f52202a4a4e4e86fd42eba7fcd999f8e1d0eb163
C#:
var token = "5f1fa09364a6ae7e35a090b434f182652ab8dd76:{\"expiration\": 1353759442.0991001, \"channel\": \"dreamhacksc2\", \"user_agent\": \".*";
var encoding = new System.Text.UTF8Encoding();
var privateKey = "Wd75Yj9sS26Lmhve";
HMACSHA1 hmac_sha1 = new HMACSHA1(encoding.GetBytes(privateKey));
hmac_sha1.Initialize();
byte[] result = hmac_sha1.ComputeHash(encoding.GetBytes(token));
string hexString = String.Join( "", result.Select( a => a.ToString("x2") ));
Console.WriteLine(hexString);
Result:
f52202a4a4e4e86fd42eba7fcd999f8e1d0eb163
Three tips:
When I tested your Java code, I received this value for str3: f52202a4a4e4e86fd42eba7fcd999f8e1d0eb163 That differs from both Java and C# result posted by you. (This online tool also calculates my result.)
Wikipedia contains an example, and it seems to be correct based on Java code and online calculator. In the first step, test your Java and C# code with the "The quick brown fox jumps over the lazy dog", "key", "de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9" triplet.
It is not a good idea using BigInterger.toString(16) converting byte array to hex string, because when the byte array begins with one ore more zero digit (or hexit?), then the converted hex string will not contains the leading 0 characters.
You are confusing bytes with strings. The result of getBytes() depends on the default character-encoding, which may be different from system to system.