public static class CryptoHelper {
// This size of the IV (in bytes) must = (keysize / 8). Default keysize is 256, so the IV must be
// 32 bytes long. Using a 16 character string here gives us 32 bytes when converted to a byte array.
private const string initVector = "pemgail9uzpgzl88";
// This constant is used to determine the keysize of the encryption algorithm
private static int keysize = 256;
private static int getKeySize()
{
return 256;
}
//Encrypt
//public static byte[] EncryptString( string plainText, string passPhrase ) {
public static byte[] EncryptString(string toEncrypt, string salt)
{
byte[] initVectorBytes = Encoding.UTF8.GetBytes(initVector);
byte[] plainTextBytes = Encoding.UTF8.GetBytes(toEncrypt);
byte[] keyBytes = new byte[126];
try
{
PasswordDeriveBytes password = new PasswordDeriveBytes(Encoding.UTF8.GetBytes(salt), null);
Debug.WriteLine(CryptoHelper.getKeySize());
Debug.WriteLine(password.ToString());
keyBytes = password.GetBytes(256 / 8);
} catch (Exception e)
{
Debug.WriteLine(e.StackTrace);
}
RijndaelManaged symmetricKey = new RijndaelManaged();
symmetricKey.Mode = CipherMode.CBC;
ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes);
MemoryStream memoryStream = new MemoryStream();
CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write);
cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
cryptoStream.FlushFinalBlock();
byte[] cipherTextBytes = memoryStream.ToArray();
memoryStream.Close();
cryptoStream.Close();
return cipherTextBytes;
}
........
The call to "password.GetBytes(256 / 8);" results in a non catchable NullReferenceException
This happens only when the UWP App is in Release mode; UWP Debug as well as Andorid and IOS are fine.
Also I get a weird Debug Message:
"this._hash" war "null".
or
"this._hash" was "null". (translated)
Here you can see it in action
VS2019 Screenshot
To repuduce this issue the inputs for the function are:
toEncrypt "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxIiwiZXhwIjoxNjE3MDAyMTEyfQ.C0CaGgfibM4z55MoANI2CiohUyew09r3_D_TpcQ6n1c8LmQd8BusSyF1SMEIQ3cO5uxE9Tnau0ZAT6D3kN3NcQ"
salt
"9x83m74tzrx9387x4mz98374zt90x8m273z948734z59"
Cause I cant see the detailed cause of this problem there it is basilcy not possible to get a workaround for this.
I was trying to make the same code work. The solution I found was to replace:
PasswordDeriveBytes password = new PasswordDeriveBytes(Encoding.UTF8.GetBytes(salt), null);
with:
Rfc2898DeriveBytes password = new Rfc2898DeriveBytes(passPhrase, Encoding.UTF8.GetBytes("12345678"));
and also add this:
symmetricKey.Padding = PaddingMode.Zeros;
Related
We're trying to encode several input strings with the same length (32) applying Blowfish + Hex encoding.
The problem is that not always the final coded strings have the same length as we expect (32 length strings).
Below you find the code used. Please, can you help to suggest what's wrong?
public static String encrypt(String clear, String key)
{
try
{
Security.setProperty("crypto.policy", "unlimited");
byte [] keyBytes = key.getBytes("ASCII");//toByteArray(key);
filelogger.info("Key coded in bytes "+keyBytes);
SecretKeySpec skey = new SecretKeySpec(keyBytes, "Blowfish");
byte [] clearBytes = clear.getBytes();//toByteArray(clear);
filelogger.info("Input string coded in bytes "+clearBytes);
Cipher ci = Cipher.getInstance("Blowfish");
ci.init(Cipher.ENCRYPT_MODE, skey);
// encrypt the clear bytes value
byte[] encoded = ci.doFinal(clearBytes);
filelogger.info("Blowfish output "+encoded);
return Base64.getEncoder().encodeToString(encoded);
}
catch (Exception e)
{
filelogger.error("Error while encrypting: " + e.toString());
logger.error("Error while encrypting: " + e.toString());
return Base64.getEncoder().encodeToString(new byte[0]);
}
}
Best regards
We have solved using the following solution:
Passing the option "Blowfish/ECB/NoPadding" to the getInstance function.
public byte[] encryptBlowfishECBNopadding(byte[] key, byte[] dati) {
byte[] output = null;
try {
SecretKeySpec KS = new SecretKeySpec(key, "Blowfish");
Cipher cipher = Cipher.getInstance("Blowfish/ECB/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, KS);
output = cipher.doFinal(dati);
return output;
} catch (Exception ee) {
logger.error(ee.getMessage());
filelogger.error(ee.toString());
return new byte[0];
}
}
Encoding the result of the method as below:
byte[] encryptresult=encryptBlowfishECBNopadding(toByteArray(decriptedki),toByteArray(criptokeyhlr.getKeydata()));
String stringencriptedki=Hex.encodeHexString(encryptresult).toUpperCase();
In this manner every output string has the same length.
Thanks to all for the support!
I have to use Aes encryption in our Xamarin PCL project. Our project uses the portable framework and not the standard so I can't use the new built in classes. I tried changing to the .NET Standard but ended up with countless errors and since I've never used it before, I figured I probably shouldn't make such a change now.
I thought this could be done using the PCLCrypto package but haven't been able to get it to work.
We currently support iOS and Android.
I'm trying to figure out how to convert the following code from our server side.
private static readonly byte[] CipherKey = ConvertHexStringToByteArray("some key");
static public string EncryptString(string originalPayload)
{
return Encrypt(originalPayload, CipherKey);
}
static private string Encrypt(string originalPayload, byte[] privateKey)
{
string encryptedPayload = "";
using (var aes = new AesCryptoServiceProvider()
{
Key = privateKey,
Mode = CipherMode.CBC,
Padding = PaddingMode.PKCS7
})
{
var input = Encoding.UTF8.GetBytes(originalPayload);
aes.GenerateIV();
var iv = aes.IV;
using (var encrypter = aes.CreateEncryptor(aes.Key, iv))
using (var cipherStream = new MemoryStream())
{
using (var tCryptoStream = new CryptoStream(cipherStream, encrypter, CryptoStreamMode.Write))
using (var tBinaryWriter = new BinaryWriter(tCryptoStream))
{
//Prepend IV to data
cipherStream.Write(iv, 0, iv.Length); //Write iv to the plain stream (not tested though)
tBinaryWriter.Write(input);
tCryptoStream.FlushFinalBlock();
}
encryptedPayload = Convert.ToBase64String(cipherStream.ToArray());
}
}
return encryptedPayload;
}
static public string DecryptString(string data)
{
return DecryptString(Convert.FromBase64String(data), CipherKey);
}
static private string DecryptString(byte[] encryptedString, byte[] encryptionKey)
{
using (var provider = new AesCryptoServiceProvider())
{
provider.Key = encryptionKey;
provider.Mode = CipherMode.CBC;
using (var ms = new MemoryStream(encryptedString))
{
// Read the first 16 bytes which is the IV.
byte[] iv = new byte[16];
ms.Read(iv, 0, 16);
provider.IV = iv;
using (var decryptor = provider.CreateDecryptor())
{
using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
{
using (var sr = new StreamReader(cs))
{
return sr.ReadToEnd();
}
}
}
}
}
}
Update
I found some code using PCLCrypto but can't get it working right. The decrypted string turns out to be squares.
Here's what I'm trying to use to decrypt the string from the server.
public static string DecryptAes(byte[] data, byte[] key)
{
ISymmetricKeyAlgorithmProvider aes = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmName.Aes,
SymmetricAlgorithmMode.Cbc, SymmetricAlgorithmPadding.None);
ICryptographicKey symetricKey = aes.CreateSymmetricKey(key);
string returnValue = "";
using (var ms = new MemoryStream(data))
{
// Read the first 16 bytes which is the IV.
byte[] iv = new byte[16];
ms.Read(iv, 0, 16);
using (var decryptor = WinRTCrypto.CryptographicEngine.CreateDecryptor(symetricKey, iv))
{
using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
{
using (var sr = new StreamReader(cs))
{
returnValue = sr.ReadToEnd();
}
}
}
}
return returnValue;
}
I was able to get it working. Here's the code in case someone runs into the same issue.
static public string Encrypt(string originalPayload, byte[] privateKey)
{
string encryptedPayload = "";
ISymmetricKeyAlgorithmProvider aes = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7);
ICryptographicKey symetricKey = aes.CreateSymmetricKey(privateKey);
var iv = WinRTCrypto.CryptographicBuffer.GenerateRandom(aes.BlockLength);
var input = Encoding.UTF8.GetBytes(originalPayload);
using (var encrypter = WinRTCrypto.CryptographicEngine.CreateEncryptor(symetricKey, iv))
{
using (var cipherStream = new MemoryStream())
{
using (var tCryptoStream = new CryptoStream(cipherStream, encrypter, CryptoStreamMode.Write))
using (var tBinaryWriter = new BinaryWriter(tCryptoStream))
{
//Prepend IV to data
cipherStream.Write(iv, 0, iv.Length); //Write iv to the plain stream (not tested though)
tBinaryWriter.Write(input);
tCryptoStream.FlushFinalBlock();
}
encryptedPayload = Convert.ToBase64String(cipherStream.ToArray());
}
}
return encryptedPayload;
}
public static string DecryptAes(byte[] data, byte[] key)
{
ISymmetricKeyAlgorithmProvider aes = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7);
ICryptographicKey symetricKey = aes.CreateSymmetricKey(key);
string returnValue = "";
using (var ms = new MemoryStream(data))
{
// Read the first 16 bytes which is the IV.
byte[] iv = new byte[16];
ms.Read(iv, 0, 16);
using (var decryptor = WinRTCrypto.CryptographicEngine.CreateDecryptor(symetricKey, iv))
{
using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
{
using (var sr = new StreamReader(cs))
{
returnValue = sr.ReadToEnd();
}
}
}
}
return returnValue;
}
This downloads a .csv file using FTP. The file is 46k on the server. When I download, it gets truncated to 44k. I have no idea why ... when I view the data in Excel, it is cut short. I increased the buffer to 4096 but no dice (this probably isn't the problem).
I originally grabbed the following code and tweaked it from: Downloading Files Using FTPWebRequest
Any thoughts appreciated ! Thanks.
private void DownloadFile(string userName, string password, string ftpSourceFilePath, string localDestinationFilePath)
{
int bytesRead = 0;
byte[] buffer = new byte[2048];
FtpWebRequest request = CreateFtpWebRequest(ftpSourceFilePath, userName, password, false);
request.Method = WebRequestMethods.Ftp.DownloadFile;
Stream reader = request.GetResponse().GetResponseStream();
FileStream fileStream = new FileStream(localDestinationFilePath, FileMode.Create);
while (true)
{
bytesRead = reader.Read(buffer, 0, buffer.Length);
if (bytesRead == 0)
break;
fileStream.Write(buffer, 0, bytesRead);
}
}
private FtpWebRequest CreateFtpWebRequest(string ftpDirectoryPath, string userName, string password, bool keepAlive)
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(new Uri(ftpDirectoryPath));
//Set proxy to null. Under current configuration if this option is not set then the proxy that is used will get an html response from the web content gateway (firewall monitoring system)
request.Proxy = null;
request.UsePassive = true;
request.UseBinary = true;
request.KeepAlive = keepAlive;
request.Credentials = new NetworkCredential(userName, password);
return request;
}
Try this approach:
private void DownloadFile(string userName, string password, string ftpSourceFilePath, string localDestinationFilePath)
{
int Length = 2048;
Byte[] buffer = new Byte[Length];
int bytesRead = responseStream.Read(buffer, 0, Length);
FtpWebRequest request = CreateFtpWebRequest(ftpSourceFilePath, userName, password, false);
request.Method = WebRequestMethods.Ftp.DownloadFile;
Stream reader = request.GetResponse().GetResponseStream();
FileStream fileStream = new FileStream(localDestinationFilePath, FileMode.Create);
while (bytesRead > 0)
{
//if (bytesRead == 0)
// break;
bytesRead = responseStream.Read(buffer, 0, Length);
fileStream.Write(buffer, 0, bytesRead);
}
fileStream.Close();
}
I'm creating an application in Silverlight that saves images in isolated storage.
I managed to save images in isolated storage but I'm having trouble by loading and displaying the image.
Here is the code:
public partial class MainPage : UserControl
{
private const string ImageName = "google1.png";
public MainPage()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
WriteableBitmap bitmap = new WriteableBitmap(saveImage, new TransformGroup());
loadedImage.Source = bitmap;
imageToStore(saveBuffer(bitmap), ImageName);
MessageBox.Show("saved");
}
public void imageToStore(byte[] buffer, string filename)
{
using (IsolatedStorageFile iso = IsolatedStorageFile.GetUserStoreForApplication())
{
IsolatedStorageFileStream s = new IsolatedStorageFileStream(filename, FileMode.Create, iso);
Int64 freeSpace = iso.AvailableFreeSpace;
Int64 needSpace = 20971520; // 20 MB in bytes
if (freeSpace < needSpace)
{
if (!iso.IncreaseQuotaTo(iso.Quota + needSpace))
{ MessageBox.Show("User rejected increase spacerequest");
}
else { MessageBox.Show("Space Increased");
}
}
using (StreamWriter writer = new StreamWriter(s))
{
writer.Write(buffer);
}
}
}
private static byte[] saveBuffer(WriteableBitmap bitmap)
{
long matrixSize = bitmap.PixelWidth * bitmap.PixelHeight;
long byteSize = matrixSize * 4 + 4;
byte[] retVal = new byte[byteSize];
long bufferPos = 0;
retVal[bufferPos++] = (byte)((bitmap.PixelWidth / 256) & 0xff);
retVal[bufferPos++] = (byte)((bitmap.PixelWidth % 256) & 0xff);
retVal[bufferPos++] = (byte)((bitmap.PixelHeight / 256) & 0xff);
retVal[bufferPos++] = (byte)((bitmap.PixelHeight % 256) & 0xff);
return retVal;
}
private void button2_Click(object sender, RoutedEventArgs e)
{
byte[] buffer = _LoadIfExists(ImageName);
loadedImage.Source = _GetImage(buffer);
MessageBox.Show("loaded");
}
private static byte[] _LoadIfExists(string fileName)
{
byte[] retVal;
using (IsolatedStorageFile iso = IsolatedStorageFile.GetUserStoreForApplication())
{
if (iso.FileExists(fileName))
{
using (IsolatedStorageFileStream stream = iso.OpenFile(fileName, FileMode.Open))
{
retVal = new byte[stream.Length];
stream.Read(retVal, 0, retVal.Length);
stream.Close();
}
}
else
{
retVal = new byte[0];
}
}
return retVal;
}
private static WriteableBitmap _GetImage(byte[] buffer)
{
int width = buffer[0] * 256 + buffer[1];
int height = buffer[2] * 256 + buffer[3];
long matrixSize = width * height;
//this is the section where Exception of type 'System.OutOfMemoryException' was thrown.
WriteableBitmap retVal = new WriteableBitmap(width, height);
int bufferPos = 4;
for (int matrixPos = 0; matrixPos < matrixSize; matrixPos++)
{
int pixel = buffer[bufferPos++];
pixel = pixel << 8 | buffer[bufferPos++];
pixel = pixel << 8 | buffer[bufferPos++];
pixel = pixel << 8 | buffer[bufferPos++];
retVal.Pixels[matrixPos] = pixel;
}
return retVal;
}}}
Hope you guys can help me. Thanks a lot.
Basically, use Silverlight to manage Image is not an easy task.
Whatever the power of the computer running your application, you are anyway limited by the browser, which by security will limit the RAM and processor dedicated to your application. (it will depend of the version of your browser, but it is roughly around 1Go of used RAM).
The only solution is to otpimize your memory management (always tricky in a managed language...):
Try to avoid your new instruction (reuse a maximum of object)
As soon as you do not need an object anymore, set its pointer to null (to keep it free to be collect by the garbage collector)
In a last option, try to call GC.Collect() in some strategic place (but be very carefull with that, your performance could dramatically decreased if you call it too often)
I need to encrypt text/files in base 64 so I can send them in an email (I can't do attachments). I can use openSSL and GPG in Linux to encrypt and decrypt but don't know how to do the same in Windows XP. Does anyone know a program that can do this for me in windows?
EDITED AGAIN
In this link you can find how to encode/decode files.
I attach sample code:
private string FileToBase64(string srcFilename)
{
if (!string.IsNullOrEmpty(srcFilename))
{
FileStream fs = new FileStream(srcFilename,
FileMode.Open,
FileAccess.Read);
byte[] filebytes = new byte[fs.Length];
fs.Read(filebytes, 0, Convert.ToInt32(fs.Length));
string encodedData = Convert.ToBase64String(filebytes,
Base64FormattingOptions.InsertLineBreaks);
return encodedData;
}
}
private void Base64ToFile(string src, string dstFilename)
{
if (!string.IsNullOrEmpty(dstFilename))
{
byte[] filebytes = Convert.FromBase64String(src);
FileStream fs = new FileStream(dstFilename,
FileMode.CreateNew,
FileAccess.Write,
FileShare.None);
fs.Write(filebytes, 0, filebytes.Length);
fs.Close();
}
}