I currently have a method which is taking a picture and saving it..
Once saved I call this method to encrypt the file from a string path
but im not sure how to save it.. I wanted to do
string path = #"C:/somePath"
File.WriteAllBytes(path);
but that doesnt work obv. So how do I properly save a bytearray?
string key = GetUniqueKey(32);
byte[] encKey = Encoding.UTF8.GetBytes(key);
byte[] imgBytes = File.ReadAllBytes(path);
byte[] ebytes = encrypt.AESEncrypt(imgBytes, encKey);
File.WriteAllBytes();
If you actually check the parameters it's asking for, you need to provide the bytes as well as the path.
So:
string path = #"C:/somePath/somefile.png"
string key = GetUniqueKey(32);
byte[] encKey = Encoding.UTF8.GetBytes(key);
byte[] imgBytes = File.ReadAllBytes(path);
byte[] ebytes = encrypt.AESEncrypt(imgBytes, encKey);
File.WriteAllBytes(path, ebytes);
Method's signature is:
File.WriteAllBytes(string path, byte[] bytes)
Related
Image files are saved in base64 string format in the database.
I'm trying to load the image using DocuVieware via MemoryStream but failed.
Does anyone tried this kind of approach?
if (this.IsPostBack != true)
{
var file = new DataFileManager().GetImageByID(userID);
byte[] byt = System.Text.Encoding.UTF8.GetBytes(file.CurrentImage);
DocuVieware1.LoadFromStream(new MemoryStream(byt, 0, byt.Length), true);
}
You probably need to replace:
byte[] byt = System.Text.Encoding.UTF8.GetBytes(file.CurrentImage);
by:
byte[] data = Convert.FromBase64String(file.CurrentImage);
Ref: https://learn.microsoft.com/en-us/dotnet/api/system.convert.frombase64string?view=netframework-4.8
I have a Base64 byte[] array which is transferred from a stream which i need to convert it to a normal byte[] how to do this ?
You have to use Convert.FromBase64String to turn a Base64 encoded string into a byte[].
This may be helpful
byte[] bytes = System.Convert.FromBase64String(stringInBase64);
Try
byte[] incomingByteArray = receive...; // This is your Base64-encoded bute[]
byte[] decodedByteArray =Convert.FromBase64String (Encoding.ASCII.GetString (incomingByteArray));
// This work because all Base64-encoding is done with pure ASCII characters
You're looking for the FromBase64Transform class, used with the CryptoStream class.
If you have a string, you can also call Convert.FromBase64String.
I've written an extension method for this purpose:
public static byte[] FromBase64Bytes(this byte[] base64Bytes)
{
string base64String = Encoding.UTF8.GetString(base64Bytes, 0, base64Bytes.Length);
return Convert.FromBase64String(base64String);
}
Call it like this:
byte[] base64Bytes = .......
byte[] regularBytes = base64Bytes.FromBase64Bytes();
I hope it helps someone.
I decided to use the SharpAESCrypt implementation of AES encryption in C#. According to their documentation (https://www.aescrypt.com/sharp_aes_crypt.html) you should be able to use a static method, providing a password string, plain-text input stream and a output stream. The data I get out of my output stream appears to be all zero's.
I suspect I am doing something wrong converting strings to a stream and back. Can anyone see anything that is obviously wrong with the code below? (It compiles and runs, but the newByteArray is filled with 0's at the end)
private void encryptMemStream()
{
byte[] byteArray = Encoding.UTF8.GetBytes(DecryptedTB.Text);
using (MemoryStream plainText = new MemoryStream(byteArray))
{
using (MemoryStream encryptedData = new MemoryStream())
{
//plainText.Write(byteArray, 0, byteArray.Length);
SharpAESCrypt.Encrypt(PasswordTB.Text, plainText, encryptedData);
encryptedData.Position = 0;
byte[] newByteArray = new byte[encryptedData.Length];
newByteArray = encryptedData.ToArray();
EncryptedTB.Text = Encoding.UTF8.GetString(newByteArray);
}
}
}
Edit: The native implementation of this code uses fileStreams, but it should work with MemoryStreams too. I will test filestreams and add my results here.
More Edits:
So when you use a file stream you call this code
//Code from the AES Crypt Library
public static void Encrypt(string password, string inputfile, string outputfile)
{
using (FileStream infs = File.OpenRead(inputfile))
using (FileStream outfs = File.Create(outputfile))
Encrypt(password, infs, outfs);
}
Which calls a function which I have been calling directly
//Code from the AES Crypt Library
public static void Encrypt(string password, Stream input, Stream output)
{
int a;
byte[] buffer = new byte[1024 * 4];
SharpAESCrypt c = new SharpAESCrypt(password, output, OperationMode.Encrypt);
while ((a = input.Read(buffer, 0, buffer.Length)) != 0)
c.Write(buffer, 0, a);
c.FlushFinalBlock();
}
There is obviously some subtle difference in using a MemoryStream and a FileStream which I don't understand. FileStream works fine, where as MemoryStream returns a blank array...
A quick code review reveals a few things including what, from discussion, seems to be the main problem you are facing. The problematic line is
EncryptedTB.Text = Encoding.UTF8.GetString(newByteArray);
This line is taking the binary data in newByteArray and telling your code that it is a valid UTF8 byte array. Chances are that it is almost certainly not actually going to be valid UTF8. Parts of it may be (such as the header) but the actually encrypted data is not going to be and so you shouldn't use this method to get a string.
If you need a printable string to put in a textbox of some sort then the correct way to do this for binary data is through base64 encoding.
EncryptedTB.Text = Convert.ToBase64String(newByteArray);
Base64 encoding effectively takes groups of three bytes (24 bits) and converts them to groups of four characters.
A further note while I'm here is that in these two lines:
byte[] newByteArray = new byte[encryptedData.Length];
newByteArray = encryptedData.ToArray();
You declare a byte array and allocate a new array to it. You then immediately discard this in favour of the array from encryptedData.ToArray(). This does not put data into the array allocated by new byte[encryptedData.Length] but creates a new array and puts it into the newByteArray variable. Better would be to just do:
byte[] newByteArray = encryptedData.ToArray();
Full working code below:
byte[] byteArray = Encoding.UTF8.GetBytes(sourceText);
Byte[] newByteArray;
using (MemoryStream plainText = new MemoryStream(byteArray))
{
using (MemoryStream encryptedData = new MemoryStream())
{
SharpAESCrypt.Encrypt(password, plainText, encryptedData);
newByteArray = encryptedData.ToArray();
}
}
EncryptedTB.Text = Convert.ToBase64String(newByteArray);
I'm trying to encrypt a text and save the encrypted text to a string
variable and a text file.
But the amazing thing is that the encrypted text in string doesn't look
the same as the encrypted text in a text file .
E.g string = bpAz1pcidPuCXbpO+5RYvQ==
textfile = n3Ö—"tû‚]ºNû”X½
I would really like my string variable to have same data as my
textfile.txt . My intension is to encrypt the string variable not the textfile.
So how do i encrypt my string variable to look the same way as my textfile data?
Here is my code below :
byte[] plainTextBytes = Encoding.UTF8.GetBytes("my name is calito");
MemoryStream memoryStream = new MemoryStream();
TripleDESCryptoServiceProvider cryptAlgorithm = new TripleDESCryptoServiceProvider();
CryptoStream csEncrypt = new CryptoStream(memoryStream, cryptAlgorithm.CreateEncryptor(), CryptoStreamMode.Write);
csEncrypt.Write(plainTextBytes, 0, plainTextBytes.Length);
//copying encrypted text to string
byte[] cipherTextBytes = memoryStream.ToArray();
string cipherText = Convert.ToBase64String(cipherTextBytes);
//copying incrypted text to text file
File.WriteAllBytes(#"G:\New Text Document.txt", memoryStream.GetBuffer());
But the amazing thing is that the encrypted text in string doesn't
look the same as the encrypted text in a text file .
That's because you are not writing the encrypted string to the file which is a Base64 representation of the actual buffer but you are writing the buffer itself. So if you wanted to write this Base64 string to the file you could use the WriteAllText method:
File.WriteAllText(#"G:\New Text Document.txt", cipherText);
What you have in the textfile are the actual bytes. What you've got in the string is the base64 encoded variant of the same bytes.
I was hoping I might get some help here so that I might finally solve this frustrating problem.
On the java side of things they sign with the following code:
public static void main(String[] args) throws Exception {
if (args.length < 2)
printInfoAndExit();
String cmd = args[0];
Security.addProvider(new BouncyCastleProvider());
Signature signature = Signature.getInstance("SHA1withRSA", "BC");
if ("sign".equalsIgnoreCase(cmd)) {
String pemFileName = args[1];
String dataFileName = args[2];
byte[] data = readFile(dataFileName);
FileReader fr = new FileReader(new File(pemFileName));
PEMReader pemReader = new PEMReader(fr);
KeyPair keyPair = (KeyPair) pemReader.readObject();
fr.close();
signature.initSign(keyPair.getPrivate());
signature.update(data);
byte[] signatureBytes = signature.sign();
writeFile(signatureBytes, dataFileName + ".signed");
String encoded = Base64.encode(signatureBytes);
writeFile(encoded.getBytes(), dataFileName + ".signed.base64");
} else {
printInfoAndExit();
}
}
When I receive the data I have their public key and try to verify with the following C# code:
public static bool Verify(String msg, String signature, String publicKey)
{
RsaKeyParameters remotepubkey = GetRsaPublicKey(publicKey);
ISigner signer = SignerUtilities.GetSigner("SHA1withRSA");
signer.Init(false, remotepubkey);
byte[] sigBytes = Convert.FromBase64String(signature);
byte[] msgBytes = Encoding.Default.GetBytes(msg);
signer.BlockUpdate(msgBytes, 0, msgBytes.Length);
return signer.VerifySignature(sigBytes);
}
This is not working!! I can however verify the data with openssl:
openssl dgst -sha1 -verify public_key.pem -signature data.txt.signed data.txt
The question is, what am I missing to make this work?
NOTE: I don't have a problem with the keys, that is working correctly but somehow there is a difference between how java and .net works with RSA?
**Edit 1 : **In this particular scenario all I had to do was change the GetSigner to
ISigner signer = SignerUtilities.GetSigner("RSA");
Could someone tell me the difference between SHA1withRSA and RSA?
The problem was actually solved on the Java side. They had some issues with their side of things.
You could have an encoding problem with your message data. You've converted the original file data into a unicode string, and are trying to convert it back to raw bytes. Depending on the encoding of the file, and if it's even text at all, your msgBytes could be different from the actual file contents.
Read the raw bytes from the file instead of a string. You don't show the code for actually reading the file data, but I assume you're reading it as text.