I have to encrypt url query sting in C# and pass to ColdFusion page. Can someone help me on writing encryption code using AES algorithm in C#.net that is equivalent to below ColdFusion function? Thanks in advance.
<cfset strLink = Encrypt("top secret", "WTq8zYcZfaWVvMncigHqwQ==", "AES","Hex")>
CF Result:
strLink = 91E72250B8A7EDBC4E5AF37F04E6AB5B
I tried below code in C#, but the results are not matching.
byte[] plainText = Encoding.Unicode.GetBytes("top secret");
byte[] key = Convert.FromBase64String("WTq8zYcZfaWVvMncigHqwQ==");
RijndaelManaged algorithm = new RijndaelManaged();
algorithm.Mode = CipherMode.ECB;
algorithm.Padding = PaddingMode.PKCS7;
algorithm.BlockSize = 128;
algorithm.KeySize = 128;
algorithm.Key = key;
string result;
using (ICryptoTransform encryptor = algorithm.CreateEncryptor())
{
using (MemoryStream memoryStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
{
cryptoStream.Write(plainText, 0, plainText.Length);
cryptoStream.FlushFinalBlock();
result = Convert.ToBase64String(memoryStream.ToArray());
}
}
}
return result;
C# Result:
HEX = 89F9F3C55CD232362FE1E14240C479BE5B56210FF3913E7B6BA4BCD3C87F9AA7
Base64 = ifnzxVzSMjYv4eFCQMR5vltWIQ/zkT57a6S808h/mqc=
(From comments...)
This is a perfect example of how character encoding makes a big difference.
Believe it or not, it is simply due to using the wrong encoding in the C# code. Encoding.Unicode uses UTF-16, whereas CF's Encrypt function always uses UTF-8 (very different). Consequently, the C# code is encrypting a totally different value than CF. Hence the different results, and why the length of the C# string (hex) is longer than the one returned from CF.
Use Encoding.UTF8.GetBytes() instead of Encoding.Unicode.GetBytes() and the results will match:
byte[] plainText = Encoding.UTF8.GetBytes("top secret");
Related
Use vfp's filetostr() function to store the string returned by the image file into the text type field of sql server
So how to create a picture file after reading a string from sql server with C#?
What encoding is the string returned by filetostr and what type is it in C#
FileToStr() reads any file either binary or not. You never store a binary file to SQL server's text field. Text data type is depreceated anyway. You use Varbinary(MAX) instead.
There is no special encoding returned with FileToStr(), it simply reads any file as is with no character encoding conversion. IOW, you can think it as ASCIIEncoding. In C# it is byte[] (not a char[]) - same as doing a File.ReadAllBytes()-. If you look a file using a hex editor, you would see hex bytes, FileToStr() gets all those bytes as a single string (unlike C#, in VFP a string can contain any ASCII character including character 0x00).
You can simply get it as a byte[] and create Image using Image.FromStream(). ie:
void Main()
{
byte[] mySavedPic;
using(SqlConnection connection = new SqlConnection(#"server=.\SQLExpress;Trusted_connection=yes;Database=ImageDb"))
{
SqlCommand cmd = new SqlCommand("select Picture from myPictures where pictureId = 1",connection);
connection.Open();
mySavedPic = (byte[])cmd.ExecuteScalar();
connection.Close();
}
Form f = new Form();
PictureBox p = new PictureBox();
p.SizeMode = PictureBoxSizeMode.StretchImage;
p.Dock = DockStyle.Fill;
using (MemoryStream ms = new MemoryStream(mySavedPic))
{
p.Image = Image.FromStream(ms);
}
f.Controls.Add( p );
f.ShowDialog();
}
I am trying to read different tag values (like tags 259 (Compression), 33432 (Copyright), 306 (DateTime), 315 (Artist) etc.) from a TIFF image in Java. Can anyone suggest what is best way to get those values in Java 11 ?
i tried to get those values using tiffinfo commands (like "tiffinfo -c myfile.tif"). But i did not find any specific command in tiffinfo (libtiff) or any Java library which will give me the specific tag values (e.g. DateTime) of a TIFF image.
Update:
As haraldK suggested, i tried with ImageIO like following
try (ImageInputStream input = ImageIO.createImageInputStream(tiffFile)) {
ImageReader reader = ImageIO.getImageReaders(input).next(); // TODO: Handle reader not found
reader.setInput(input);
IIOMetadata metadata = reader.getImageMetadata(0);
TIFFDirectory ifd = TIFFDirectory.createFromMetadata(metadata);
TIFFField dateTime = ifd.getTIFFField(306);
String dateString = dateTime.getAsString(0);
}
But it does not give exact value of the tag. In case of non-ASCII value (ö, ü, ä etc), question marks replace the real values.
Can anyone tell me how to get the exact value (including non-ASCII) of the tag from TIFFField ?
You can use standard ImageIO, read the TIFF image metadata and get the requested values from it, like this by using some extra support classes in the JDK, starting from Java 9:
try (ImageInputStream input = ImageIO.createImageInputStream(tiffFile)) {
ImageReader reader = ImageIO.getImageReaders(input).next(); // TODO: Handle reader not found
reader.setInput(input);
IIOMetadata metadata = reader.getImageMetadata(0); // 0 is the index of first image
TIFFDirectory ifd = TIFFDirectory.createFromMetadata(metadata);
TIFFField dateTime = ifd.getTIFFField(306); // Yes, that's 3 F's...
String dateString = dateTime.getAsString(0); // TIFF dates are strings...
}
tiffFile must be a valid (existing, readable) java.io.File, java.io.RandomAccessFile or java.io.InputStream (or other supported input, this is plugin-based, really). If not, input will be null, and the code will fail.
You can use similar, but a lot more verbose version, that will work in older versions of Java, as long as you have a TIFF plugin:
try (ImageInputStream input = ImageIO.createImageInputStream(tiffFile)) {
ImageReader reader = ImageIO.getImageReaders(input).next(); // TODO: Handle reader not found
reader.setInput(input);
IIOMetadata metadata = reader.getImageMetadata(0); // 0 is the index of first image
// Get "native" TIFF metadata for first IFD
IIOMetadataNode root = metadata.getAsTree("com_sun_media_imageio_plugins_tiff_image_1.0");
Node ifd = root.getFirstChild();
NodeList fields = ifd.getElementsByTagName("TIFFField"); // Yes, that's 3 F's...
for (int i = 0; i < fields.getLength(); i++) {
Element field = (Element) fields.item(i);
if ("306".equals(field.getAttribute("number"))) {
// This is your DateTime (306) tag,
// now do something with it 😀
// ...
}
}
}
Hardly elegant code, though... The Java 9+ approach is much cleaner and easier to reason about.
In my qna maker knowledge base I have this:
Question:
Hello
Answer:
Hello maría
But I got this answer on the bot: Hello maría . I tried many things and there is no results.
Thanks.
you can use the below code where you are getting your response from QNA and pass it to code.
static void Main()
{
string unicodeString = "This string contains the unicode character Pi (\u03a0)";
// Create two different encodings.
Encoding ascii = Encoding.ASCII;
Encoding unicode = Encoding.Unicode;
// Convert the string into a byte array.
byte[] unicodeBytes = unicode.GetBytes(unicodeString);
// Perform the conversion from one encoding to the other.
byte[] asciiBytes = Encoding.Convert(unicode, ascii, unicodeBytes);
// Convert the new byte[] into a char[] and then into a string.
char[] asciiChars = new char[ascii.GetCharCount(asciiBytes, 0, asciiBytes.Length)];
ascii.GetChars(asciiBytes, 0, asciiBytes.Length, asciiChars, 0);
string asciiString = new string(asciiChars);
// Display the strings created before and after the conversion.
Console.WriteLine("Original string: {0}", unicodeString);
Console.WriteLine("Ascii converted string: {0}", asciiString);
}
do let me know in case you need more help
I have created a sample here:
https://github.com/FranciscoPonceGomez/FranciscoQnAccents
It works in all channels for me. You should not have any problems with accents.
Knowledge Base:
You can try it here:
https://franciscoqnaccents.azurewebsites.net/
Let me know if there is anything in the code that doesn't make sense to you.
Regards,
Francisco
I have mp4 files in Isolated Storage and I am reading this by using IsolatedStorageFileStream. After read the file I need to convert it into b64 string.
So I am not getting proper code for this. If anyone knows then please help me.
//Convert the IsolatedStorageFileStream to Base64 String and take the length of the file.
BinaryReader reader = new BinaryReader(isoVideoFile);
long length = reader.BaseStream.Length;
int rr = Convert.ToInt32(length);
byte[] chunk = reader.ReadBytes(rr);//reading the bytes
string temp_inBase64 = Convert.ToBase64String(chunk);
You can use Convert.ToBase64String(bytes[])
I'm trying to get as3crypto to play nice with either Gibberish or EzCrypto in AES-128 mode.
No matter what combination of settings I use I simply cannot get one to decrypt the other, and usually get a "bad decrypt" message in ruby. Each contained environment can decrypt data it encrypted itself but one cannot seem to decrypt the other.
Has anyone been able to get the two to work together?
Here's one of the variations I tried:
On the Actionscript side, using as3crypto:
//define the encryption key
var key:ByteArray = Hex.toArray("password");
//put plaintext into a bytearray
var plainText:ByteArray = Hex.toArray(Hex.fromString("this is a secret!"));
//set the encryption key
var aes:AESKey = new AESKey(key);
//encrypt the text
aes.encrypt( plainText );
trace(Base64.encode(Hex.fromArray(plainText)));
//encrypted value is N2QwZmI0YWQ4NzhmNDNhYjYzM2QxMTAwNGYzNDI1ZGUyMQ==
And on the ruby side, using gibberish:
// also tried the default size (256)
cipher = Gibberish::AES.new("password",128)
// raises the following exception: OpenSSL::Cipher::CipherError: wrong final block length
cipher.dec("N2QwZmI0YWQ4NzhmNDNhYjYzM2QxMTAwNGYzNDI1ZGUyMQ==")
I've tried all sort of different approaches, all yielding either the above exception or "bad encrypt"
Finally figured it out myself. The thing is both Gibberish and EzCrypto do not seem to provide a way to specify an IV, which is needed when using aes-cbc. The trick is to extract the iv from the first 16 bytes of the encrypted data as3crypto produces.
Here's the as3 code, which also changed a little:
// there are other ways to create the key, but this works well
var key:ByteArray = new ByteArray();
key.writeUTFBytes(MD5.encrypt("password"));
// encrypt the data. simple-aes-cbc is equiv. to aes-256-cbc in openssl/ruby, if your key is
// long enough (an MD5 is 32 bytes long)
var data:ByteArray = Hex.toArray(Hex.fromString("secret"));
var mode:ICipher= Crypto.getCipher("simple-aes-cbc", key) ;
mode.encrypt(data);
// the value here is base64, 32 bytes long. the first 16 bytes are the IV, needed to decrypt
// the data in ruby
// e.g: sEFOIF57LVGC+HMEI9EMTpcJdcu4J3qJm0PDdHE/OSY=
trace(Base64.encodeByteArray(data));
The ruby part uses a gem called encryptor to supply the iv.
you can also use OpenSSL directly, it's pretty straight forward:
key = Digest::MD5.hexdigest("password")
// decode the base64 encoded data back to binary:
encrypted_data = Base64.decode64("sEFOIF57LVGC+HMEI9EMTpcJdcu4J3qJm0PDdHE/OSY=")
// the tricky part: extract the IV from the decoded data
iv = encrypted_data.slice!(0,16)
// decrypt!
Encryptor.decrypt(encrypted_data,:key=>key,:iv=>iv)
// should output "secret"