Fast RSA encryption in AS3 - performance

I have a Flex 4 application that uses a 2048 bits private RSA key to encrypt/sign some string values that are around 30 characters long.
I'm currently using the com.hurlant.crypto.RSAKey implementation to do so but I'm facing the following limitations:
It takes way too long (around 4 seconds for signing a 30 chars
string)
The UI freezes while the class is processing (implementation obviously doesn't
use events or chunks processing)
I have been looking for other libraries but I haven't found so far any other with the same level of functionalities (read RSA key from PEM string, allow RSA.sign(), RSA.encrypt and decrypt), that is free to use in commercial applications and that is faster than the one I currently use.
So my questions are:
Does anyone know a great/fast AS3 library that do that?
If there are none and I decide to write one myself from scratch will I be
facing the same problems because the low performances are somehow induced by the
flash platform ?
EDIT2: Below code uses a PEM encoded private key stored in a file. If you don't have one you can create one using the following piece of code:
var exp:String = "10001";
var bits:int = 2048;
rsa = RSAKey.generate(bits, exp);
Don't forget to sit down and take a coffee as it takes nearly one minute to generate.
EDIT: Here is piece of code showing the limitations.
Simply click on the start button and see how the progress bar and the application completely freezes.
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Script>
<![CDATA[
import com.hurlant.crypto.rsa.RSAKey;
import com.hurlant.util.der.PEM;
import mx.utils.Base64Encoder;
var pkfilePath:String = "/Users/david/Desktop/private_key.pem";
var stringToSign:String = "Hello this is a string to be signed by an efficient AS3 library";
private function readPKContent():String {
var f:File = new File(pkfilePath);
var fs:FileStream = new FileStream();
fs.open(f,FileMode.READ);
var rawKey:String = fs.readUTFBytes(fs.bytesAvailable);
fs.close();
return rawKey;
}
private function logTime(msg:String, start:Date, end:Date):void {
resultTA.text = msg + " " + (end.time-start.time) + " ms\n" + resultTA.text;
}
protected function button1_clickHandler(event:MouseEvent):void
{
cryptWithHurlant();
}
private function cryptWithHurlant():void {
var start:Date = new Date();
//Load key and use it to sign something
var rawPK:String = readPKContent();
var time:Date = new Date();
var rsa:RSAKey = PEM.readRSAPrivateKey(rawPK);
logTime("Hurlant:ReadRSA", time, new Date());
//Compute a signature of the string
var srcBA:ByteArray = new ByteArray();
srcBA.writeUTFBytes(stringToSign);
//Now sign inside the second BA
var desBA:ByteArray = new ByteArray();
time = new Date();
rsa.sign(srcBA, desBA, srcBA.length);
logTime("Hurlant:Encrypt", time, new Date());
//desBA.position = 0;
//Recover as a Base64 response
//var b64encoder:Base64Encoder = new Base64Encoder();
//time = new Date();
//b64encoder.encodeBytes(desBA);
//logTime("Base64:Encoded "+b64encoder.toString(),time, new Date());
logTime("Hurlant:Total",start,new Date());
}
]]>
</fx:Script>
<s:VGroup width="100%" height="100%" horizontalAlign="center">
<s:Button click="button1_clickHandler(event)" label="Start"/>
<mx:ProgressBar indeterminate="true"/>
<s:TextArea width="100%" height="100%" editable="false" id="resultTA"/>
</s:VGroup>
</s:WindowedApplication>

As noted above:
You may want to look into this timer based "threading" implementation. This won't speed anything up, but it will get rid of the UI lock. I have code using this working on mobile.
Based on all that has been said in comments and the absence of answers, I think that my best option for now will be to edit the RSA implementation to make it able to run with the pseudo-threading model proposed by f-a. I will move to workers once they are supported by mobile platforms.
References
Threads in ActionScript 3
flash.system.Worker

Related

How do I create an HTML-formatted ICS message body using ical.net?

I need send reminders to users of a web application.
To do this I use iCal.Net from nuget packages. Following instructions about the usage I'm able to send an email with an attachment containing the ics file.
Is it possible to format the event description as html and make it working on both Outlook office client and Chrome calendar?
On these clients I see plain text representation with all the html tags. I tested also on Windows 10 calendar where the event description is correctly displayed as html. Do I have to set something more?
This is my calendar string generation
var now = DateTime.Now;
var later = scadenza.Value;
var e = new Event
{
DtStart = new CalDateTime(later),
DtEnd = new CalDateTime(later),
Description = mailText,
IsAllDay = true,
Created = new CalDateTime(DateTime.Now),
Summary = $"Reminder for XYZ",
};
var attendee = new Attendee
{
CommonName = "…..",
Rsvp = true,
Value = new Uri("mailto:" + ConfigurationManager.AppSettings["ReminderReceiver"])
};
e. Attendees = new List<IAttendee> { attendee };
var calendar = new Calendar();
calendar.Events.Add(e);
var serializer = new CalendarSerializer(new SerializationContext());
var icalString = serializer.SerializeToString(calendar);
HTML formatting isn't part of the icalendar spec, so it's up to applications to add support for this via the non-standard property fields, which are designated with an X- prefix. (Further reading on non-standard properties if you're interested.)
Google calendar
It doesn't look like Google calendar has any support for HTML-formatted events, so I think you're out of luck there.
Outlook
Outlook uses a number of these X- fields for various things; for HTML-formatted descriptions, it uses X-ALT-DESC and specifies FMTTYPE=text/html like this:
X-ALT-DESC;FMTTYPE=text/html:<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//E
N">\n<HTML>\n<HEAD>\n<META NAME="Generator" CONTENT="MS Exchange Server ve
rsion rmj.rmm.rup.rpr">\n<TITLE></TITLE>\n</HEAD>\n<BODY>\n<!-- Converted
from text/rtf format -->\n\n<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Cali
bri">This is some</FONT></SPAN><SPAN LANG="en-us"><B> <FONT FACE="Calibri"
>HTML</FONT></B></SPAN><SPAN LANG="en-us"><FONT FACE="Calibri"></FONT></SP
AN><SPAN LANG="en-us"><U> <FONT FACE="Calibri">formatted</FONT></U></SPAN>
<SPAN LANG="en-us"><FONT FACE="Calibri"></FONT></SPAN><SPAN LANG="en-us"><
I> <FONT FACE="Calibri">text</FONT></I></SPAN><SPAN LANG="en-us"><FONT FAC
E="Calibri">.</FONT></SPAN><SPAN LANG="en-us"></SPAN></P>\n\n</BODY>\n</HT
ML>
You may be able to get away with much simpler HTML, you'll have to test to see what Outlook supports/allows. The HTML block above was generated using Outlook 2013. I have successfully used that block and run it through a serialization round-trip with ical.net, and Outlook opens it without any fuss.
ical.net
Unfortunately you can't quite do this in ical.net due a bug with CalendarProperty serialization, but the workaround is just one line.
const string formatted = //the text block from above starting with FMTTYPE=text/html:
var start = DateTime.Now;
var end = start.AddHours(1);
var #event = new Event
{
Start = new CalDateTime(start),
End = new CalDateTime(end),
Description = "This is a description",
};
var property = new CalendarProperty("X-ALT-DESC", formatted);
#event.AddProperty(property);
var calendar = new Calendar();
calendar.Events.Add(#event);
var serialized = new CalendarSerializer().SerializeToString(calendar);
//Workaround for the bug:
serialized = serialized.Replace("X-ALT-DESC:FMTTYPE=text/html", "X-ALT-DESC;FMTTYPE=text/html");
This will produce HTML-formatted Outlook calendar events.
(When I fix the bug, I'll update this answer to remove the string.Replace call.)

Dynamics CRM Attachment Data Import Using SDK

I am trying to import Attachments/Annotations to CRM Dynamics, I am doing this using the SDK.
I am not using the data import wizard.
I am not individually creating Annotation entities, instead I am using Data Import Feature programmatically.
I mostly leveraged the DataImport sample from the SDK sample code (SDK\SampleCode\CS\DataManagement\DataImport).
Import import = new Import()
{
ModeCode = new OptionSetValue((int)ImportModeCode.Create),
Name = "Data Import"
};
Guid importId = _serviceProxy.Create(import);
_serviceProxy.Create(
new ColumnMapping()
{
ImportMapId = new EntityReference(ImportMap.EntityLogicalName, importMapId),
ProcessCode = new OptionSetValue((int)ColumnMappingProcessCode.Process),
SourceEntityName = sourceEntityName,
SourceAttributeName = sourceAttributeName,
TargetEntityName = targetEntityName,
TargetAttributeName = targetAttributeName
});
I am getting an error "The reference to the attachment could not be found".
The documentation says the crm async service will find the physical file on disk and upload it, my question is where does the async service look for attachment files?
I tried to map documentbody field to the full path of the attachment on the desk, but that still didn't work.
The answer below was provided before the question edits clarifying the use of the import wizard instead of the SDK. The answer below is specific to using the SDK.
When you are attaching files to an Annotation (Note) record in CRM via the SDK, you do use the documentbody attribute (along with mimetype), but you have to first convert it base64.
Something like this:
var myFile = #"C:\Path\To\My\File.pdf";
// Do checks to make sure file exists...
// Convert to Base64.
var base64Data = Convert.ToBase64String(System.IO.File.ReadAllBytes(myFile));
var newNote = new Entity("annotation");
// Set subject, regarding object, etc.
// Add the data required for a file attachment.
newNote.Attributes.Add("documentbody", base64Data);
newNote.Attributes.Add("mimetype", "text/plain"); // This mime type seems to work for all file types.
orgService.Create(newNote);
I found the solution in an obscure blog post, I think the documentation is misleading or unclear, the way this whole thing works, makes having the files available on the server disk for the async to process, odd.
To follow the same principle, all contents should be sent like the csv file itself while being linked to the same import.
To solve this we need create individual special Internal ImportFile for each physical attachment, and link it to the import that has the attachments record details.
As you see below with linking the attachments ImportFile using the ImportId and then setting the two properties (ProcessCode and FileTypeCode), it all worked in the end.
Suffice to say using this method is much more efficient and quicker than individually creating Annotation records.
foreach (var line in File.ReadLines(csvFilesPath + "Attachment.csv").Skip(1))
{
var fileName = line.Split(',')[0].Replace("\"", null);
using (FileStream stream = File.OpenRead(attachmentsPath + fileName))
{
byte[] byteData = new byte[stream.Length];
stream.Read(byteData, 0, byteData.Length);
stream.Close();
string encodedAttachmentData = System.Convert.ToBase64String(byteData);
ImportFile importFileAttachment = new ImportFile()
{
Content = encodedAttachmentData,
Name = fileName,
ImportMapId = new EntityReference(ImportMap.EntityLogicalName, importMapId),
UseSystemMap = true,
ImportId = new EntityReference(Import.EntityLogicalName, importId),
ProcessCode = new OptionSetValue((int)ImportFileProcessCode.Internal),
FileTypeCode = new OptionSetValue((int)ImportFileFileTypeCode.Attachment),
RecordsOwnerId = currentUserRef
};
_serviceProxy.Create(importFileAttachment);
}
idx++;
}

Firefox estensions: programmatically add a certificate to the trust certificate store

I am trying to understand how to add a certificate in the store of trusted certificates in FF. I could not find a clear answer so far, but doing some research I understand it should be doable with a firefox extension. This may be an hint:
https://developer.mozilla.org/en-US/Add-ons/Code_snippets/Miscellaneous#Adding_custom_certificates_to_a_XULRunner_application
Does anyone know how to do this with modern versions of FF? is there any best practices?
Thank in advance,
Stefano
just to answer my own question... after some additional research I managed to do it and I believe what's in the article is quite accurate. you do not need necessarily to build an XPCOM though.
I have just created a simple add on with the code below:
function addCertificate() {
var certDB = Cc["#mozilla.org/security/x509certdb;1"].getService(Ci.nsIX509CertDB);
var is = Cc["#mozilla.org/scriptableinputstream;1"].getService(Ci.nsIScriptableInputStream);
var file = new FileUtils.File("/tmp/famfor.crt");
var channel = gIOService.newChannelFromURI(gIOService.newFileURI(file));
var input = channel.open();
is.init(input);
var envelope = is.read(input.available());
is.close();
input.close();
var beginCert = "-----BEGIN CERTIFICATE-----";
var endCert = "-----END CERTIFICATE-----";
envelope = envelope.replace(/[\r\n]/g, "");
var begin = envelope.indexOf(beginCert);
var end = envelope.indexOf(endCert);
var cert = envelope.substring(begin + beginCert.length, end);
console.log(cert);
certDB.addCertFromBase64(cert, "C,C,C", "");
};
Quite straightforward I would say :)

Dynamically added Raddocks Optimization?

We have a optimization problem regarding rad dock controls. The requirement of project is such that we are creating dynamic raddocks on the fly and adding it to a raddockzone, then we are saving the raddock "type" etc in a mssql db. We also have a collector window/raddockzone in which we have build a functionality where we can drag a dock and save it in collector. As with the first raddockzone we are adding the dock in collector on the fly. Now while adding a dock or moving it to another raddockzones it takes sometime. Our client is comparing it with the example of the demo link : http://demos.telerik.com/aspnet-ajax/dock/examples/content/defaultcs.aspx
Following is our code snippet to add dock on the fly:
private RadDockNew CreateRadDock()
{
//string[] allowedZones = { "RDZCollector", "RadDockZone2" };
int width = Convert.ToInt32((hdnWidth.Value == "") ? "520" : hdnWidth.Value);
RadDockNew dock = new RadDockNew();
dock.DockMode = DockMode.Docked;
dock.UniqueName = Guid.NewGuid().ToString().Replace("-", "a");
dock.ID = string.Format("RadDock{0}", dock.UniqueName);
//dock.Title = dock.UniqueName.Substring(dock.UniqueName.Length - 3);
dock.Width = Unit.Pixel(width);
dock.CssClass = "RadDockZoneMain";
//dock.AllowedZones = allowedZones;
dock.Style.Add("min-height", "290px");
dock.OnClientDockPositionChanged = "DropInCollector";
//dock.EnableViewState = false;
DockCommand cmd = new DockCommand();
cmd.Name = "Setting";
cmd.Text = "Setting";
cmd.OnClientCommand = "showSettings";
dock.Commands.Add(cmd);
DockCommand dc = new DockCommand();
dc.Text = "Trash";
dc.Name = "Trash";
dc.OnClientCommand = "CloseDock";
dc.CssClass = "rdClose";
dc.AutoPostBack = true;
dock.Commands.Add(dc);
DockToggleCommand cmd2 = new DockToggleCommand();
cmd2.CssClass = "rdCollapse";
cmd2.AlternateCssClass = "rdexpand";
cmd2.OnClientCommand = "ChangeImage";
//DockCommand collapse = new DockCommand();
//collapse.Text = "Collapse/Expand";
//collapse.Name = "Collapse/Expand";
//collapse.OnClientCommand = "CollapseDock";
//collapse.CssClass = "rdCollapse";
dock.Commands.Add(cmd2);
return dock;
}
Please tell if there is any way to optimize / make it faster.
Thanks.
I examined the attached code sample and I think that it is correct. My suggestions are to check if the problem persists if you use other storage medium, instead of a database or if there are client script errors on the page, containing the RadDocks.
As the setup of your project seems to be similar to the one, implemented in the My Portal demo, I would recommend using the example in the Code Library article Saving State of Dynamically Created RadDocks in DataBase using Hidden UpdatePanel as a reference.

Loading from 2 urlloaders in an order and maintaining the flow in FLEX

I have a flex application where on creationComplete i call a method in which i needed to load two XML files frm the server.only after which i need to proceed further..
Currently i am doing the following
onCreationComplete = init();
private function init():void{
//loading first XML
urlReq = new URLRequest(PATH_FOR_XML1);
urlLdr = new URLLoader(urlReq);
urlLdr.addEventListener(Event.COMPLETE, doEvent);
//Some other operation goes here say SOMEGREATWORK
}
**doEvent method**
private function doEvent(evt:Event):void{
//Loading the data of XML1 to some variable which i use application wide
urlReq = new URLRequest(PATH_FOR_XML2);
urlLdr = new URLLoader(urlReq);
urlLdr.addEventListener(Event.COMPLETE, loadXML2);
}
private function loadXML2(evt:Event):void{
//Loading the data of XML2 to the some varibale which i use application Wide
}
What actually i was doing is ,once the loading of one URL completed, i load data from it and the starting the loading of second URL loader from the same method.
But the problem is
i dont want SOMEGREATWORK block to be executed before the 2 XMLs are loaded to application variables
because in SOMEGREATWORK block , i will be using the them and by the time this executes, sometimes the variables are not loaded properly.
Try this:
onCreationComplete = init();
private function init():void{
//loading first XML
urlReq = new URLRequest(PATH_FOR_XML1);
urlLdr = new URLLoader(urlReq);
urlLdr.addEventListener(Event.COMPLETE, doEvent);
}
private function doEvent(evt:Event):void{
//Loading the data of XML1 to some variable which i use application wide
urlReq = new URLRequest(PATH_FOR_XML2);
urlLdr = new URLLoader(urlReq);
urlLdr.addEventListener(Event.COMPLETE, loadXML2);
}
private function loadXML2(evt:Event):void{
//Some other operation goes here say SOMEGREATWORK
}

Resources