String value system.byte[] while coverting Base64 value to string in c# - c#

I have two LDIF files from where I am reading values and using it for comparsion using c#
One of the attribute: value in LDIF is a base64 value, need to convert it in UTF-8 format
displayName:: Rmlyc3ROYW1lTGFzdE5hbWU=
So I thought of using string -> byte[], but I am not able to use the above displayName value as string
byte[] newbytes = Convert.FromBase64String(displayname);
string displaynamereadable = Encoding.UTF8.GetString(newbytes);
In my C# code, I am doing this to retrieve the values from the ldif file
for(Entry entry ldif.ReadEntry() ) //reads value from ldif for particular user's
{
foreach(Attr attr in entry) //here attr gives attributes of a particular user
{
if(attr.Name.Equals("displayName"))
{
string attVal = attr.Value[0].ToString(); //here the value of String attVal is system.Byte[], so not able to use it in the next line
byte[] newbytes = Convert.FromBase64String(attVal); //here it throws an error mentioned below
string displaynamereadable = Encoding.UTF8.GetString(attVal);
}
}
}
Error:
The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters.
I am trying to user attVal as String so that I can get the encoded UTf-8 value but its throwing an error.
I tried to use BinaryFormatter and MemoryStream as well, it worked but it inserted so many new chars with the original value.
Snapshot of BinaryFormatter:
object obj = attr.Value[0];
byte[] bytes = null;
BinaryFormatter bf = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream())
{
bf.Serialize(ms, obj);
bytes = (ms.ToArray());
}
string d = Encoding.UTF8.GetString(bytes);
So the result after encoding should be: "FirstNameLastName"
But it gives "\u0002 \u004 \u004 ...................FirstNameLastName\v"
Thanks,

Base64 was designed to send binary data through transfer channels that only support plain text, and as a result, Base64 is always ASCII text. So if attr.Value[0] is a byte array, just interpret those bytes as string using ASCII encoding:
String attVal = Encoding.ASCII.GetString(attr.Value[0] as Byte[]);
Byte[] newbytes = Convert.FromBase64String(attVal);
String displaynamereadable = Encoding.UTF8.GetString(newbytes);
Also note, your code above was feeding attVal into that final line rather than newbytes.

Related

c# - base64 jpeg to MemoryStream?

I have a base64 jpeg like so: data:image/jpeg;base64 and I am trying to convert it to a MemoryStream so I can upload it to OneDrive....Here is what I got so far:
byte[] frontBytes = Convert.FromBase64String(user.FrontLicense);
using (MemoryStream frontMS = new MemoryStream(frontBytes))
{
await graphClient.Me.Drive.Items[newFolder.Id].ItemWithPath("FrontLicense.jpeg").Content.Request().PutAsync<DriveItem>(frontMS);
}
But I get this error:
The input is not a valid Base-64 string as it contains a non-base 64
character, more than two padding characters, or an illegal character
among the padding characters.
On this line:
byte[] frontBytes = Convert.FromBase64String(user.FrontLicense);
This is what user.FrontLicense looks like:
data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoM.....
What am I doing wrong?
The part at the start - data:image/jpeg;base64, - isn't part of the base64 data. So you need to remove that first:
const string Base64ImagePrefix = "data:image/jpeg;base64,"
...
if (user.FrontLicense.StartsWith(Base64ImagePrefix))
{
string base64 = user.FromLicense.Substring(Base64ImagePrefix.Length);
byte[] data = Convert.FromBase64String(base64);
// Use the data
}
else
{
// It didn't advertise itself as a base64 data image. What do you want to do?
}

File ReadAllLines and Unicode Encoding

I have a file which has unicode of a byte array which is a serialized object.
I tried reading that file using the code below.
string unicodeString = File.ReadAllText(filename);
This works fine, when i tried to get that Byte array back, for deserialization.
What I am looking for is, read only the particular lines of a file and try to convert that unicode string to bytes. For that I tried.
string unicodeString = string.join("", File.ReadAllLines(filename).Take(4).ToArray());
Here I used 4 because, the file has 4 lines of unicode string
byte[] _bytes = System.Text.Encoding.Unicode.GetBytes(unicodeString );
var bformatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
using (var ms = new MemoryStream(_bytes))
{
myobject data = (myobject)bformatter.Deserialize(ms);
}
I can able to get the string but unable to deserialize. My objective is to I will many such objects in the file and I'll retrieve only those lines and deserialize that to object.
It throws the following exception.
{"Binary stream '0' does not contain a valid BinaryHeader. Possible causes are invalid stream or object version change between serialization and deserialization."}

UtF-8 gives extra string in German character

I have file name testtäöüßÄÖÜ . I want to convert in UTF-8 using c#.
string test ="testtäöüß";
var bytes = new List<byte>(test.Length);
foreach (var c in test)
bytes.Add((byte)c);
var retValue = Encoding.UTF8.GetString(bytes.ToArray());
after running this code my output is : 'testt mit Umlaute äöü?x. where mit Umlaute is extra
text.
Can anybody help me ?
Thanks in advance.
You can't do that. You can't cast an UTF-8 character to byte. UTF-8 for anything other than ASCII requires at least two bytes, byte can can't store this
Instead of creating a list, use
byte[] bytes = System.Text.Encoding.UTF8.GetBytes (test);
I think, Tseng means the following
Taken from: http://www.chilkatsoft.com/p/p_320.asp
System.Text.Encoding utf_8 = System.Text.Encoding.UTF8;
// This is our Unicode string:
string s_unicode = "abcéabc";
// Convert a string to utf-8 bytes.
byte[] utf8Bytes = System.Text.Encoding.UTF8.GetBytes(s_unicode);
// Convert utf-8 bytes to a string.
string s_unicode2 = System.Text.Encoding.UTF8.GetString(utf8Bytes);
MessageBox.Show(s_unicode2);

Error in converting from Encrypted value

I have a encryption method GetDecryptedSSN(). I tested it’s correctness by the following test. It works fine
//////////TEST 2//////////
byte[] encryptedByteWithIBMEncoding2 = DecryptionServiceHelper.GetEncryptedSSN("123456789");
string clearTextSSN2 = DecryptionServiceHelper.GetDecryptedSSN(encryptedByteWithIBMEncoding2);
But when I do a conversion to ASCII String and then back, it is not working correctly. What is the problem in the conversion logic?
//////////TEST 1//////////
//String -- > ASCII Byte --> IBM Byte -- > encryptedByteWithIBMEncoding
byte[] encryptedByteWithIBMEncoding = DecryptionServiceHelper.GetEncryptedSSN("123456789");
//encryptedByteWithIBMEncoding --> Encrypted Byte ASCII
string EncodingFormat = "IBM037";
byte[] encryptedByteWithASCIIEncoding = Encoding.Convert(Encoding.GetEncoding(EncodingFormat), Encoding.ASCII,
encryptedByteWithIBMEncoding);
//Encrypted Byte ASCII - ASCII Encoded string
string encodedEncryptedStringInASCII = System.Text.ASCIIEncoding.ASCII.GetString(encryptedByteWithASCIIEncoding);
//UpdateSSN(encodedEncryptedStringInASCII);
byte[] dataInBytesASCII = System.Text.ASCIIEncoding.ASCII.GetBytes(encodedEncryptedStringInASCII);
byte[] bytesInIBM = Encoding.Convert(Encoding.ASCII, Encoding.GetEncoding(EncodingFormat),
dataInBytesASCII);
string clearTextSSN = DecryptionServiceHelper.GetDecryptedSSN(bytesInIBM);
Helper Class
public static class DecryptionServiceHelper
{
public const string EncodingFormat = "IBM037";
public const string SSNPrefix = "0000000";
public const string Encryption = "E";
public const string Decryption = "D";
public static byte[] GetEncryptedSSN(string clearTextSSN)
{
return GetEncryptedID(SSNPrefix + clearTextSSN);
}
public static string GetDecryptedSSN(byte[] encryptedSSN)
{
return GetDecryptedID(encryptedSSN);
}
private static byte[] GetEncryptedID(string id)
{
ServiceProgram input = new ServiceProgram();
input.RequestText = Encodeto64(id);
input.RequestType = Encryption;
ProgramInterface inputRequest = new ProgramInterface();
inputRequest.Test__Request = input;
using (MY_Service operation = new MY_Service())
{
return ((operation.MY_Operation(inputRequest)).Test__Response.ResponseText);
}
}
private static string GetDecryptedID(byte[] id)
{
ServiceProgram input = new ServiceProgram();
input.RequestText = id;
input.RequestType = Decryption;
ProgramInterface request = new ProgramInterface();
request.Test__Request = input;
using (MY_Service operationD = new MY_Service())
{
ProgramInterface1 response = operationD.MY_Operation(request);
byte[] encodedBytes = Encoding.Convert(Encoding.GetEncoding(EncodingFormat), Encoding.ASCII,
response.Test__Response.ResponseText);
return System.Text.ASCIIEncoding.ASCII.GetString(encodedBytes);
}
}
private static byte[] Encodeto64(string toEncode)
{
byte[] dataInBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(toEncode);
Encoding encoding = Encoding.GetEncoding(EncodingFormat);
return Encoding.Convert(Encoding.ASCII, encoding, dataInBytes);
}
}
REFERENCE:
Getting incorrect decryption value using AesCryptoServiceProvider
This is the problem, I suspect:
string encodedEncryptedStringInASCII =
System.Text.ASCIIEncoding.ASCII.GetString(encryptedByteWithASCIIEncoding);
(It's not entirely clear because of all the messing around with encodings beforehand, which seems pointless to me, but...)
The result of encryption is not "text encoded in ASCII" - so you shouldn't try to treat it that way. (You haven't said what kind of encryption you're using, but it would be very odd for it to produce ASCII text.)
It's just an arbitrary byte array. In order to represent that in text only using the ASCII character set, the most common approach is to use base64. So the above code would become:
string encryptedText = Convert.ToBase64(encryptedByteWithIBMEncoding);
Then later, you'd convert it back to a byte array ready for decryption as:
encryptedByteWithIBMEncoding = Convert.FromBase64String(encryptedText);
I would strongly advise you to avoid messing around with the encodings like this if you can help it though. It's not clear why ASCII needs to get involved at all. If you really want to encode your original text as IBM037 before encryption, you should just use:
Encoding encoding = Encoding.GetEncoding("IBM037");
string unencryptedBinary = encoding.GetBytes(textInput);
Personally I'd usually use UTF-8, as an encoding which can handle any character data rather than just a limited subset, but that's up to you. I think you're making the whole thing much more complicated than it needs to be though.
A typical "encrypt a string, getting a string result" workflow is:
Convert input text to bytes using UTF-8. The result is a byte array.
Encrypt result of step 1. The result is a byte array.
Convert result of step 2 into base64. The result is a string.
To decrypt:
Convert the string from base64. The result is a byte array.
Decrypt the result of step 1. The result is a byte array.
Convert the result of step 2 back to a string using the same encoding as step 1 of the encryption process.
In DecryptionServiceHelper.GetEncryptedSSN you are encoding the text in IBM037 format BEFORE encrypting.
So the following piece of code is not correct as you are converting the encrypted bytes to ASCII assuming that its in the IBM037 format. That's wrong as the encrypted bytes is not in IBM037 format (the text was encoded before encryption)
//encryptedByteWithIBMEncoding --> Encrypted Byte ASCII
string EncodingFormat = "IBM037";
byte[] encryptedByteWithASCIIEncoding = Encoding.Convert(Encoding.GetEncoding(EncodingFormat), Encoding.ASCII,
encryptedByteWithIBMEncoding);
One possible solution is to encode the encrypted text using IBM037 format, that should fix the issue I guess.

Invalid length for a Base-64 char array

I'm getting a "Invalid length for a Base-64 char array." inside of the IF(){...} are variations i have tried to get it to work. it fails in the first line without calling decrypt(...) proving it's not that functions problem. i get the same error inside with the first decrypt(...) call. the last one using the encoding.ascii... will get me inside the function, but then it fails inside the function. I'm getting the proper encrypted info from the database to string SSnum. it's value is: 4+mFeTp3tPF
try
{
string SSnum = dr.GetString(dr.GetOrdinal("Social Security"));
if (isEncrypted)
{
byte[] temp = Convert.FromBase64String(SSnum);
//SSnum = decrypt(Convert.FromBase64String(SSnum), Key, IV);
//SSnum = decrypt(Encoding.ASCII.GetBytes(SSnum), Key, IV);
}
txt_Social_Security.Text = SSnum;
}
catch { txt_Social_Security.Text = ""; }
I've been told to use the Convert.FromBase64String() and not the ASCII method...so why is it failing, how can i fix it?
Base64 data length should be multiple of 4 and with padding char '='
You can change your data as valid base64 data.
string dummyData = imgData.Trim().Replace(" ", "+");
if (dummyData.Length % 4 > 0)
dummyData = dummyData.PadRight(dummyData.Length + 4 - dummyData.Length % 4, '=');
byte[] byteArray = Convert.FromBase64String(dummyData);
https://stackoverflow.com/a/9301545/2024022
This will help you , try once.
Thanks
suribabu.
it's value is: 4+mFeTp3tPF
You are receiving this error because that value, 4+mFeTp3tPF, is in fact not valid Base64.
Is it possible you are simply missing the required padding character, as so 4+mFeTp3tPF=?
Are you certain that you have a Base64 string? Base64 is a means of encoding binary data into a string while only using standard 7-bit ASCII characters. It's not a string encoding like ASCII and has some control bytes present. You have a Base64 string if you're using Convert.ToBase64String to obtain the value (which, if you're trying to store binary data as a string, is your best bet)
Judging by your error (and your example data), I'm assuming that you do not have a Base64 string. If you need to store binary data in the database, you can either create a column using a binary type or encode the string into Base64 by using Convert.ToBase64String.
byte[] inputData = ...;
string base64String = Convert.ToBase64String(inputData);
byte[] outputData = Convert.FromBase64String(base64String);
Here, outputData should contain the same data as inputData.
If what you have is just an ASCII-encoded string, then your original practice of using System.Text.Encoding.ASCII.GetBytes() is correct, but you should change this to use a Base64 string if you can.
Are you sure that string 4+mFeTp3tPF is well-formed Base64 string?
I've tried some online services - no one could convert it.
replace
byte[] temp = Convert.FromBase64String(SSnum);
to this
var temp = UTF8Encoding.UTF8.GetBytes(SSnum);

Categories