What is proper encoding for converting a string to a byte array - asp.net

I am having some sort of problem with encoding in my ASP.NET HTTPHandler, which uploads a file. The file content is passed in a hidden form variable from a ColdFusion web page which is using something called "ToBase64".
In ColdFusion, the code used to place the file content into a form is as follows:
<cffile action="readBinary" file="#FileName#" variable="objBinaryData">
<cfset b64file = #toBase64(objBinaryData)#>
<form name="sendToHandler"
action="http://myserver/mysite/UploadHandler.ashx" method="post">
<cfoutput>
<input type="hidden" name="objBinaryData" value="#b64file#" />
When my UploadHandler.ashx is posted, I am getting a string out of the form as follows:
string fileContent = context.Request.Form["objBinaryData"];
Next, I am converting the string to a byte array as follows:
byte[] binData = StringToByteArray(fileContent, EncodingType.ASCII);
Here is the function I'm using to convert the string:
public static byte[] StringToByteArray(string str, EncodingType encodingType)
{
System.Text.Encoding encoding = null;
switch (encodingType)
{
case EncodingType.ASCII:
encoding = new System.Text.ASCIIEncoding();
break;
case EncodingType.Unicode:
encoding = new System.Text.UnicodeEncoding();
break;
case EncodingType.UTF7:
encoding = new System.Text.UTF7Encoding();
break;
case EncodingType.UTF8:
encoding = new System.Text.UTF8Encoding();
break;
}
return encoding.GetBytes(str);
}
public enum EncodingType
{
ASCII,
Unicode,
UTF7,
UTF8
}
It's obvious to me that calling the above function with EncodingType.ASCII is wrong but I am very confused about what would be correct? What is the proper "match" between "Base64" sent from ColdFusion and the way the string should be encoded in .Net?
Please note that all the code "works" but the subsequent retrieval of a file shows it to be scrambled and I'm pretty sure I have the wrong encoding here.
EDIT-update:
I added the enum code previously omitted. I've tried all of these Encoding Types; they all result in "garbage". That is: I have tried each of these variations:
byte[] binData = StringToByteArray(fileContent, EncodingType.ASCII);
byte[] binData = StringToByteArray(fileContent, EncodingType.Unicode);
byte[] binData = StringToByteArray(fileContent, EncodingType.UTF7);
byte[] binData = StringToByteArray(fileContent, EncodingType.UTF8);
None of these work properly. As I read your suggested function, it should be Unicode. Note that I want to return a byte array not a converted string. Still very confused.
ANSWER:
I simply eliminated the enum and the function I wrote called StringToByteArray. Instead I coded the following:
byte[] binData = Convert.FromBase64String(fileContent);

Look at the Convert.FromBase64String() function

Base64 is an encoding scheme that enables you to represent binary data as a series of ASCII characters so that it can be included in text files and e-mail messages in which raw binary data is unacceptable. The below examples show encoding and decoding of unicode strings. Let me know if this is what you wanted,if not I can refind this further for you.
//Encoding
public static string StringToBase64 (string src) {
// Get's byte representation unicode string
byte[] b = Encoding.Unicode.GetBytes(src);
// Returns Base64-encoded string
return Convert.ToBase64String(b);
}
//Decoding
public static string Base64ToString (string src) {
// Decodes Base64-encoded string to a byte array
byte[] b = Convert.FromBase64String(src);
// Returns decoded Unicode string
return Encoding.Unicode.GetString(b);
}

Related

I am trying to decode and extract octet string from the extension of X509Certificate, but I did not get any valid string

I have been trying to decode the octet string as per steps mentioned in
https://developer.apple.com/documentation/devicecheck/validating_apps_that_connect_to_your_server?language=objc
Here is what I have tried:
X509Certificate cert1 = getParentCertificate(new String(decodedCredCert));
System.out.println(cert1);
cert1.checkValidity(); // verify against apple app attest root ca
byte[] ext = cert1.getExtensionValue("1.2.840.113635.100.8.2");
ASN1InputStream bIn = new ASN1InputStream(ext);
ASN1Primitive obj = bIn.readObject();
ASN1OctetString string = (ASN1OctetString) obj;
byte[] octs = string.getOctets();
ASN1InputStream dIn = new ASN1InputStream(octs);
String octetString = ASN1Dump.dumpAsString(dIn.readObject());
I got the output as: "[[1]#8333585e692916d8cbcdce3c6aa2bd71617d54fed758957cfd6b50a2093fd506]"
For Ios AppAttestation, follow as below to get the extension value and it's corresponding octet string. As mentioned in that page,
Obtain the value of the credCert extension with OID
1.2.840.113635.100.8.2, which is a DER-encoded ASN.1 sequence. Decode the sequence and extract the single octet string that it contains.
Here is the sample code:
byte[] oidValue = credCert.getExtensionValue(ooid);
DEROctetString envelope = (DEROctetString) new ASN1InputStream(oidValue).readObject();
DLSequence sequence = (DLSequence) new ASN1InputStream(envelope.getOctetStream()).readObject();
DLTaggedObject taggedObject = (DLTaggedObject) sequence.getObjectAt(0);
DEROctetString taggedObjectOctet = (DEROctetString) taggedObject.getObject();
log.debug("Octet String : {}", taggedObjectOctet.getOctets());
"Octet string" is just a spec phrase that modern languages call "byte array". You've extracted the value as of octs, and should compare that value to whatever nonce you're supposed to compare it against.

How to get Binary data with javascript using FileReader api with correct encoding

I got a mp4 data using FileReader api, but I have a problem at encoding!
With this function,
var reader = new FileReader();
var blob = new Blob([this.response], {type : "video/mp4"});
reader.onload= function (evt) {
mp4text = evt.target.result;
mp4text = mp4text.toString()
//mp4text = mp4text.slice(22);
//mp4text = CryptoJS.AES.encrypt(mp4text, "test");
//mp4text = window.atob(mp4text);
var myBlob = new Blob([evt.target.result], {type : "video/mp4"});//NOT SAME contrast to blob!
var downloadUrl = URL.createObjectURL(myBlob);
document.getElementById('myVideo').src = downloadUrl;
}
reader.readAsBinaryString(blob);
I thought myBlob has same filedata as blob but some data changed! With more detail, Many of character are same but some hex code is different. How can I solve this problem?
Strings in JavaScript cannot represent arbitrary binary data, so doing readAsBinaryString may not be what you think.
What readAsBinaryString does is for each source byte it gives you a destination character(I don't which character encoding it uses off the top of my head).
So if you have a utf-8 character say ✔, then readAsBinaryString will give you â since that character is tree bytes long %E2%9C%94.
If you try to turn this back to binary/blob the string â is treated as utf-8 which is not 3 bytes but 7(%C3%A2%C5%93%E2%80%9D)
My suggestion would be to use readAsArrayBuffer, I'm sure CryptoJS supports arraybuffers.

sending email with utf-8 characters in the subject

I'm using ActionMailer.net to send email.
No matter what I do I can not get the subject in utf-8, it displays just question marks. Body shows in utf-8.
This is my last attempt to solve the issue:
public EmailResult AccountConfirmationEmail(AccountConfirmationModel acm)
{
MailAttributes.MessageEncoding = Encoding.UTF8;
MailAttributes.To.Add(new MailAddress(acm.BizUserId));
MailAttributes.From = new MailAddress("service#abc.co.il");
UTF8Encoding utf8 = new UTF8Encoding();
string unicodeString = "אישור הרשמה לאתר";
byte[] encodedBytes = utf8.GetBytes(unicodeString);
MailAttributes.Subject = Encoding.UTF8.GetString(encodedBytes, 0, encodedBytes.Length);
return Email("Account/AccountConfirmationEmail", acm);
}
to no avail.
Does anyone know how to do this?

Decode S-JIS string to UTF-8

I am working on a Japanese File and I have no knowledge of the language. The file is encoded in S-JIS. Now, I am supposed to convert the contents into UTF-8 so that the content looks like Japanese. And here I am completely blank. I tried the following code that I found somewhere on Internet but no luck:
byte[] arrByte = Encoding.UTF8.GetBytes(arrActualData[x]);
string str = ASCIIEncoding.ASCII.GetString(arrByte);
Can anyone help me with this?
Thanks in advance
Kunal
In C#, the following code works for me.
I wanted to try this out so evidence of my results below:
public void Convert()
{
using (TextReader input = new StreamReader(
new FileStream("shift-jis.txt", FileMode.Open),
Encoding.GetEncoding("shift-jis")))
{
using (TextWriter output = new StreamWriter(
new FileStream("utf8.txt", FileMode.Create), Encoding.UTF8))
{
var buffer = new char[512];
int len;
while ((len = input.Read(buffer, 0, 512)) > 0)
{
output.Write(buffer, 0, len);
}
}
}
}
Shown here is the file encoded in shift-jis (or SJIS/Shift_JIS they are the same), using JEdit to verify the encoding (the word in the file is the japanese text テスト meaning test):
After running the code & opening the file written to (utf8.txt) :
But it should be said that such a file conversion does not strictly require knowledge of any language.

Generating multipart boundary

I'm writing a script that uploads a file to a cgi script that expects a multipart request, such as a form on a HTML page. The boundary is a unique token that annotates the file contents in the request body. Here's an example body:
--BOUNDARY
Content-Disposition: form-data; name="paramname"; filename="foo.txt"
Content-Type: text/plain
... file contents here ...
--BOUNDARY--
The boundary cannot be present in the file contents, for obvious reasons.
What should I do in order to create an unique boundary? Should I generate a random string, check to see if it is in the file contents, and if it is, generate a new, rinse and repeat, until I have a unique string? Or would a "pretty random token" (say, combination of timestamp, process id, etc) be enough?
If you use something random enough like a GUID there shouldn't be any need to hunt through the payload to check for an alias of the boundary. Something like:-
----=NextPart_3676416B-9AD6-440C-B3C8-FC66DDC7DB45
Header:....
Payload
----=NextPart_3676416B-9AD6-440C-B3C8-FC66DDC7DB45--
For Java guys :
protected String generateBoundary() {
StringBuilder buffer = new StringBuilder();
Random rand = new Random();
int count = rand.nextInt(11) + 30; // a random size from 30 to 40
for (int i = 0; i < count; i++) {
buffer.append(MULTIPART_CHARS[rand.nextInt(MULTIPART_CHARS.length)]);
}
return buffer.toString();
}
private final static char[] MULTIPART_CHARS =
"-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
.toCharArray();
Reference url : http://hc.apache.org/httpcomponents-client-ga/httpmime/xref/org/apache/http/entity/mime/MultipartEntity.html
And for the Swift people (to balance the Java):
func createBoundaryString() -> String {
var str = ""
let length = arc4random_uniform(11) + 30
let charSet = [Character]("-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
for _ in 0..<length {
str.append(charSet[Int(arc4random_uniform(UInt32(charSet.count)))])
}
return str
}
If you are feeling paranoid, you can generate a random boundary and search for it in the string to be sent, append random char (or re-create new) on find, repeat. But my experience is any arbitrary non-dictionary string of 10 or so characters is about impossible to occur, so picking something like ---BOUNDARY---BOUNDARY---BOUNDARY--- is perfectly sufficient.

Resources