I get string messages from the clients which needs to be authenticated in the server.
I need to ensure that I (the server) got the exact string content which was sent by the client. I don't care about the client identity. Just the message.
I thought of using hashcode or CRC algorithm.
Do you have any suggestions/best practices for it?
Thanks a lot,
Adi Barda
To make certain the string is identical, then yes, a hash will do the job. The only problem you will encounter is that if the server has nothing to match to, all you will have is that the string you have is the same as the string that was hashed.
Any language you are using in particular?
Here's an example in C#, which hashes a string then converts into Base64:
public static string QHash(string str)
{
SHA512 SHA512HashCreator = SHA512.Create();
byte[] EncryptedData = SHA512HashCreator.ComputeHash(Encoding.UTF8.GetBytes(str));
StringBuilder qhash = new StringBuilder();
for (int i = 0; i < EncryptedData.Length; i++)
{
qhash.Append(EncryptedData[i].ToString("X2"));
}
return qhash.ToString().ToUpper();
}
Related
//This is how I am calling from controller
var signature = Request.Headers["X-Docusign-Signature-1"];
var message = Request.Body;
StreamReader reader1 = new StreamReader(message);
string text = reader1.ReadToEnd();
var isValid = docuSignHMACKeyValidation.HashIsValid(text, signature);
// My Methods
public string ComputeHash(string secret, string payload)
{
byte[] bytes = Encoding.UTF8.GetBytes(secret);
HMAC hmac = new HMACSHA256(bytes);
bytes = Encoding.UTF8.GetBytes(payload);
return Convert.ToBase64String(hmac.ComputeHash(bytes));
}
public bool HashIsValid(string payload, string verify)
{
string secret = "secretkey";
ReadOnlySpan<byte> hashBytes =
Convert.FromBase64String(ComputeHash(secret, payload));
ReadOnlySpan<byte> verifyBytes = Convert.FromBase64String(verify);
return CryptographicOperations.FixedTimeEquals(hashBytes, verifyBytes);
}
I'm a little suspicious of your line
bytes = Encoding.UTF8.GetBytes(payload);
I'd try it without an encoding conversion.
Also:
Check that the hmac signature is in X-Docusign-Signature-1 (check that you only have one hmac secret set in DocuSign.)
Use your debugger to check each step and compare with the results from a HMAC checking web site such as https://www.freeformatter.com/hmac-generator.html In other words, first check that you can use the online tool to verify the hmac. Then debug your code to determine why your getting a false response.
Have been stringbuilding CSV files for ages on MVC applications just fine, until now.
One mistake made me generate a CSV string bigger then the system can handle in memory, so i have been searching the web for any solution on minifing a string that could be reconstructed back on client.
So far i have been doing this:
StringBUilder sb = new StringBuilder();
foreach(stuff in manyEnumerableStuff)
sb.Append(stuff);
return csv.ToString().ToBase64();
public static string ToBase64(this string value) => Convert.ToBase64String(Encoding.Default.GetBytes(value));
The application can handle .ToString() in this HUGE case just "fine", but it fails without creating excpetions at .ToBase64String(Encoding.Default.GetBytes(value));
This only happens on huge strings because from what i know, base64 will make the string 33% bigger.
Compressed json can't solve this problem, since this happens on server side.
So I have gonne on search to minify or compress this string, but it still need to be a string and can be converted on client site Angular application.
I have found this:
public static string compress(this string big) {
var bytes = Encoding.Default.GetBytes(big);
using (var msi = new MemoryStream(bytes))
using (var mso = new MemoryStream()) {
using (var gs = new GZipStream(mso, CompressionMode.Compress)) {
//msi.CopyTo(gs);
CopyTo(msi, gs);
}
return mso.ToArray().ToString();
}
}
private static void CopyTo(Stream src, Stream dest) {
byte[] bytes = new byte[4096];
int cnt;
while ((cnt = src.Read(bytes, 0, bytes.Length)) != 0) {
dest.Write(bytes, 0, cnt);
}
}
but I think there is no sense at all, because i can't put byte[] on json value as string without converting it back.
Is it possible to compress plain Pipe separated values that represents a .CSV file after getting the string from StringBuilder()?
I have tried GC.collect() right after parsing SB to string but still broke the application.
I'm on .Net Core 2.1, Linux server.
The below simple java code getting Fortify Path Manipulation error. Please help me to resolve this. I am struggling from long time.
public class Test {
public static void main(String[] args) {
File file=new File(args[0]);
}
}
Try to normalize the URL before using it
https://docs.oracle.com/javase/7/docs/api/java/net/URI.html#normalize()
Path path = Paths.get("/foo/../bar/../baz").normalize();
or use normalize from org.apache.commons.io.FilenameUtils
https://commons.apache.org/proper/commons-io/javadocs/api-1.4/org/apache/commons/io/FilenameUtils.html#normalize(java.lang.String)
Stirng path = FilenameUtils.normalize("/foo/../bar/../baz");
For both the result will be \baz
Looking at the OWASP page for Path Manipulation, it says
An attacker can specify a path used in an operation on the filesystem
You are opening a file as defined by a user-given input. Your code is almost a perfect example of the vulnerability! Either
Don't use the above code (don't let the user specify the input file as an argument)
Let the user choose from a list of files that you supply (an array of files with an integer choice)
Don't let the user supply the filename at all, remove the configurability
Accept the vulnerability but protect against it by checking the filename (although this is the worst thing to do - someone may get round it anyway).
Or re-think your application's design.
Fortify will flag the code even if the path/file doesn't come from user input like a property file. The best way to handle these is to canonicalize the path first, then validate it against a white list of allowed paths.
Bad:
public class Test {
public static void main(String[] args) {
File file=new File(args[0]);
}
}
Good:
public class Test {
public static void main(String[] args) {
File file=new File(args[0]);
if (!isInSecureDir(file)) {
throw new IllegalArgumentException();
}
String canonicalPath = file.getCanonicalPath();
if (!canonicalPath.equals("/img/java/file1.txt") &&
!canonicalPath.equals("/img/java/file2.txt")) {
// Invalid file; handle error
}
FileInputStream fis = new FileInputStream(f);
}
Source: https://www.securecoding.cert.org/confluence/display/java/FIO16-J.+Canonicalize+path+names+before+validating+them
Only allow alnum and a period in input. That means you filter out the control chars, "..", "/", "\" which would make your files vulnerable. For example, one should not be able to enter /path/password.txt.
Once done, rescan and then run Fortify AWB.
I have a solution to the Fortify Path Manipulation issues.
What it is complaining about is that if you take data from an external source, then an attacker can use that source to manipulate your path. Thus, enabling the attacker do delete files or otherwise compromise your system.
The suggested remedy to this problem is to use a whitelist of trusted directories as valid inputs; and, reject everything else.
This solution is not always viable in a production environment. So, I suggest an alternative solution. Parse the input for a whitelist of acceptable characters. Reject from the input, any character you don't want in the path. It could be either removed or replaced.
Below is an example. This does pass the Fortify review. It is important to remember here to return the literal and not the char being checked. Fortify keeps track of the parts that came from the original input. If you use any of the original input, you may still get the error.
public class CleanPath {
public static String cleanString(String aString) {
if (aString == null) return null;
String cleanString = "";
for (int i = 0; i < aString.length(); ++i) {
cleanString += cleanChar(aString.charAt(i));
}
return cleanString;
}
private static char cleanChar(char aChar) {
// 0 - 9
for (int i = 48; i < 58; ++i) {
if (aChar == i) return (char) i;
}
// 'A' - 'Z'
for (int i = 65; i < 91; ++i) {
if (aChar == i) return (char) i;
}
// 'a' - 'z'
for (int i = 97; i < 123; ++i) {
if (aChar == i) return (char) i;
}
// other valid characters
switch (aChar) {
case '/':
return '/';
case '.':
return '.';
case '-':
return '-';
case '_':
return '_';
case ' ':
return ' ';
}
return '%';
}
}
Assuming you're running Fortify against a web application, during your triage of Fortify vulnerabilities that would likely get marked as "Not an issue". Reasoning being A) obviously this is test code and B) unless you have multiple personality disorder you're not going to be doing a path manipulation exploit against your self when you run that test app.
If very common to see little test utilities committed to a repository which produces this style of false positive.
As for your compilation errors, that generally comes down to classpath issues.
We have code like below which was raising Path Manipulation high category issue in fortify .
String.join(delimeter,string1,string2,string2,string4);
Our program is to deal with AWS S3 bucket so, we changed as below and it worked .
com.amazonaws.util.StringUtils.join(delimeter,string1,string2,string2,string4);
Using the Tika library FilenameUtils.normalize solves the fortify issue.
import org.apache.tika.io.FilenameUtils;
public class Test {
public static void main(String[] args) {
String filePath = FilenameUtils.normalize(args[0]); //This line solve issue.
File file=new File(filePath);
}
}
Try this for replacing FileInputStream. You will need to close your project and open again to accurately see whether changes worked.
File to byte[] in Java
Use Normalize() function in C# and it resolved the fortify vulnerability in next scan.
string s = #:c:\temp\scan.log".Normalize();
Use regex to validate the file path and file name
fileName = args[0];
final String regularExpression = "([\\w\\:\\\\w ./-]+\\w+(\\.)?\\w+)";
Pattern pattern = Pattern.compile(regularExpression);
boolean isMatched = pattern.matcher(fileName).matches();
I have a website in asp.net 2.0, As I need to use CCNOW payment integration to make a payment but for this I'll have to send request to CCNOW in MD5 format but I can't able to generate my values to CCNOW MD5 format. So, could you please any one have a script/function that will convert given string into MD5?
MD5 isn't a "format," is a hashing algorithm. Use the MD5 class. Assuming you're using C#, it would look something like this:
static string getMd5Hash(string input)
{
// Create a new instance of the MD5CryptoServiceProvider object.
MD5 md5Hasher = MD5.Create();
// Convert the input string to a byte array and compute the hash.
byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input));
// Create a new Stringbuilder to collect the bytes
// and create a string.
StringBuilder sBuilder = new StringBuilder();
// Loop through each byte of the hashed data
// and format each one as a hexadecimal string.
for (int i = 0; i < data.Length; i++)
{
sBuilder.Append(data[i].ToString("x2"));
}
// Return the hexadecimal string.
return sBuilder.ToString();
}
public static string GetMD5(string value) {
MD5 md5 = MD5.Create();
byte[] md5Bytes = System.Text.Encoding.Default.GetBytes(value);
byte[] cryString = md5.ComputeHash(md5Bytes);
string md5Str = string.Empty;
for (int i = 0; i < cryString.Length; i++) {
md5Str += cryString[i].ToString("X");
}
return md5Str;
}
Call it with:
GetMD5(stringToConvert);
i want to Encrypt and Decrypt data in J2ME using AES Algorithm with bouncy castle
can any one give me sample code for that
i want to use ECB with PKCS5Padding
Thanks in Advance.
I'm sure there are examples out there but I haven't found them. Here are a few hints to help you get started. You need to learn how to connect the BC classes together. First, get the bouncycastle source code and be prepared to look at it when you have questions. It's actually very readable so don't be afraid to examine it when the documentation is poor. For example, many classes want an instance of a CipherParameters object, but it is rare for the documentation to specify any more detail. However, in the source code it will be obvious as to which implementing classes are expected.
Choose one of the AES engines, for example AESEngine, as the encryption engine. Next pick a mode; ECB is rarely correct, so for example if you pick CBC mode then create a CBCBlockCipher object from your AESEngine object. Next, use this object to create a PaddedBufferBlockCipher object. The default constructor uses PKCS7 padding which is identical to the PKCS5 padding you want. Now you need to create an object to hold the key and IV. This is the CipherParameters interface. You create the object in two steps. First, you create a KeyParameter object with your key. Next, you create a ParametersWithIV object with your KeyParameter object and your IV. This object is supplied to the init method of the PaddedBufferBlockCipher object and then your are ready to go.
EDIT
Here is small example:
private static byte[] cipherData(PaddedBufferedBlockCipher cipher, byte[] data)
throws Exception
{
int minSize = cipher.getOutputSize(data.length);
byte[] outBuf = new byte[minSize];
int length1 = cipher.processBytes(data, 0, data.length, outBuf, 0);
int length2 = cipher.doFinal(outBuf, length1);
int actualLength = length1 + length2;
byte[] result = new byte[actualLength];
System.arraycopy(outBuf, 0, result, 0, result.length);
return result;
}
private static byte[] decrypt(byte[] cipher, byte[] key, byte[] iv) throws Exception
{
PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(new CBCBlockCipher(
new AESEngine()));
CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key), iv);
aes.init(false, ivAndKey);
return cipherData(aes, cipher);
}
private static byte[] encrypt(byte[] plain, byte[] key, byte[] iv) throws Exception
{
PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(new CBCBlockCipher(
new AESEngine()));
CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key), iv);
aes.init(true, ivAndKey);
return cipherData(aes, plain);
}