Jan Keijzer’s Weblog

21/02/2011

Mooi!

Gearchiveerd onder: Muziek — Jan Keijzer @ 22:24

19/11/2010

Silverlight: Hoe refereer je een image, die in je XAP-file staat?

Gearchiveerd onder: C#, Silverlight — Jan Keijzer @ 17:34

Af en toe is het nodig om een resource uit je eigen XAP-file te refereren. Er zijn veel voorbeelden te vinden op internet hoe je dat met WPF doet. Maar die werken vaak niet omdat de Assembly.GetName() functie in Silverlight niet werkt (zie referentie hieronder). In Silverlight werkt de volgende methode het beste:

// Get the simple name of the application
string appName = Application.Current.GetType().Assembly.FullName.Split (',') [0];

// Get the string that points to the image file in the subfolder Images
string uriStr = "/" + appName + ";component/Images/" + imageFilename;

// Get the relative URI
Uri uri = new Uri(uriStr, UriKind.Relative);

// Create the ImageSource for the image
ImageSource imgSource = new BitmapImage(uri);

Let op de “/”, waarmee de uriString start.

Referenties:

16/11/2010

MVVM en MEF: Verdere verdieping

Gearchiveerd onder: C#, Publiek, Silverlight — Tags:, — Jan Keijzer @ 21:46

Hieronder een lijstje met artikel, die mij meer inzicht gaven in het werken met MEF en MVVM:

Verder een mooie serie van Glenn Block over het gebruik van MEF in Silverlight 4:

En later nog een mooie serie van Jeremy Likeness over het gebruik van PRISM, MEF en MVVM:

12/11/2010

Encryptie met Silverlight en Decryptie met PHP

Gearchiveerd onder: C#, PHP, Publiek, Security, Silverlight — Tags:, , , — Jan Keijzer @ 15:03

Ik had behoefte aan een manier om strings van Silverlight te encrypten en die met PHP te decrypten. Mijn vraag was hoe doe je dat?

In eerste instantie dacht ik dat het nodig was om een encryptie/decryptie algoritme te kiezen en daarvan een versie te hebben voor Silverlight en voor PHP. Daarbij kwam ik op een elegant algoritme uit, dat niet te veel processorkracht nodig had het TEA-algoritme. Maar daarmee was het probleem niet direct lekker opgelost. Want je moet dan ook een implementatie hebben. In ons geval aan de server kant een PHP-versie. En aan de client kant het liefst een C# versie. Maar bij het zoeken naar zo’n implementatie is het erg oppassen geblazen. Want er blijken verschillende varianten van het TEA algoritme te zijn. Een originele versie (TEA), een verbeterde versie (XTEA) en een nogmaals verbeterde versie (XXTEA). Soms is het duidelijk om welke versie het gaat, maar soms moet je het uit de code zelf halen. Bovendien geven sommige implementaties slechts een interface naar ruwe encryptie / decryptie methodes, waarbij je byte-arrays van een lengte van 8 bytes converteert. Om dan strings te kunnen converteren, moet je nog wat extra code maken, die string pad met spaties.

Al met al had ik op basis van een aantal artikelen een C# versie geproduceerd, die compatibel was met een PHP en Javascript implementatie van Babelfish.nl. Maar na verschillende mislukte pogingen om de Silverlight zijde met de PHP-zijde te laten praten, heb ik het maar opgegeven om op deze weg verder te gaan.

Volgende stap was om gebruik te maken van algoritmes, die al standaard in Silverlight en PHP zitten. En dan maar hopen dat die algoritmes ook met elkaar willen praten. Dat bleek nog een hele klus. Maar uiteindelijk is het me gelukt om een goed werkend encryptie / decryptie mechanisme te bewerkstelligen tussen Silverlight en PHP. Het algoritme dat ik daarvoor heb gebruikt is het AES algoritme. Het artikel, waar ik uiteindelijk de code aan te danken heb was: The PHP-silverlight Cryptography Challenge (hoewel in dat artikel nog een foutje zat met verkeerde lengtes van de key en de initialization vector en, naar zeggen van de auteur, de MD5 hash over het password). Verder heb ik veel hulp gehad van een artikel van Chilkat Software, Inc.:Understanding PHP AES Encryption

Uiteindelijk ziet mijn code er nu als volgt uit:
AesCryptographer.cs

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace Aduba.Cryptography
{
    public class AesCryptographer
    {
        private byte[] mKey = null;
        private byte[] mIV = null;

        public string Key { set { mKey = Encoding.UTF8.GetBytes(value); } }
        public string IV { set { mIV = Encoding.UTF8.GetBytes(value); } }

        public string EncryptAes128(string plainText)
        {
            byte[] data;
            byte[] encryptedData;

            // convert the plain text to a byte array
            data = Encoding.UTF8.GetBytes(plainText);

            // encrypt the plain text
            encryptedData = EncryptAes128(data);

            // convert to Base64 in order to transfer over internet.
            return Convert.ToBase64String(encryptedData);
        }

        public byte[] EncryptAes128(byte[] plainData)
        {
            MemoryStream MStream = new MemoryStream(); // Memory stream to write encrypted data to.
            CryptoStream CryptoStream = null;
            AesManaged A128 = new AesManaged();
            try
            {
                //Create aes128 Encryptor from this instance.
                ICryptoTransform A128Encrypt = A128.CreateEncryptor(mKey, mIV);
                //Create Crypto Stream that transforms memory stream using aes encryption.
                using (CryptoStream = new CryptoStream(MStream, A128Encrypt, CryptoStreamMode.Write))
                {
                    //Write out and flush AES encrypted data to memory stream.
                    CryptoStream.Write(plainData, 0, plainData.Length);
                    CryptoStream.FlushFinalBlock();
                }
                // Return encrypted data.
                return MStream.ToArray();
            }
            catch (Exception ex)
            {
                return null;
            }
            finally
            {
                if (CryptoStream != null) { CryptoStream.Close(); };
                if (MStream != null) { MStream.Close(); }
            }
        }

        public byte[] DecryptAes128(byte[] EncryptedByteData)
        {
            MemoryStream MStream = null; // Memory stream to write encrypted data to.
            CryptoStream CryptoStreamDecr = null;
            AesManaged A128 = new AesManaged();
            try
            {
                //Create aes128 instance and Decryptor.
                ICryptoTransform A128Decrypt = A128.CreateDecryptor(mKey, mIV);
                //Create crypto stream set to read and do a AES decryption transform on incoming bytes.
                MStream = new MemoryStream(EncryptedByteData);
                CryptoStreamDecr = new CryptoStream(MStream, A128Decrypt, CryptoStreamMode.Read);
                //Get the decrypted bytes.
                byte[] DestArray = new BinaryReader(CryptoStreamDecr).ReadBytes((int)MStream.Length * 2);
                //Return decrypted data.
                return DestArray;
            }
            catch (Exception ex)
            {
                return null;
            }
            finally
            {
                if (MStream != null) { MStream.Close(); }
            }
        }

    }
}

En de PHP-code voor de decryptie:

function aes128cbcDecrypt($key, $encrypted_text, $iv) {
    $td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
    mcrypt_generic_init($td, $key, $iv);
    $decrypted = mdecrypt_generic($td, $encrypted_text);
    $decrypted = removePadding($decrypted);
    mcrypt_generic_deinit($td);
    mcrypt_module_close($td);
    return trim($decrypted);
}

function removePadding($text) {
    $block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
    $packing = ord($text{strlen($text) - 1});
    if ($packing and ($packing < $block)) {
        for ($P = strlen($text) - 1; $P >= strlen($text) - $packing; $P--) {
            if (ord($text{$P}) != $packing) {
                $packing = 0;
            }
        }
    }
    return substr($text, 0, strlen($text) - $packing);
}

Deze decryptie functie wordt aangeroepen door:

$encryptedData = $_REQUEST['Cipher'];
$data = base64_decode($encryptedData);
$plainText = aes128cbcDecrypt($key, $data, $iv);

Een volledige PHP AES Klasse is te vinden via de volgende link:
http://www.phpclasses.org/browse/file/23124.html

11/11/2010

iTunes opstarten met het Logitech Internet 350 Keyboard

Gearchiveerd onder: Geen categorie — Tags:, — Jan Keijzer @ 11:06

Ik wilde vandaag eens iTunes opstarten met de op de Logitech Internet 350 Keyboard aanwezige Multimedia knop. Dit bleek toch meteen weer een echte zoektocht. Uiteindelijk erachter gekomen dat het wel te doen is en dat er een aantal leuke mogelijkheden zijn als je ook nog sciprts gebruikt voor de iTunes Application.

In het kort komt het op het volgende neer.

Het keyboard stuur bij het indrukken van een knop een code naar de PC. Deze code kan de Windows Explorer dan interpreteren naar een op te starten programma of associëren met een filetype. Welke codes met programma of filetype is geassocieerd staat in het Register onder de volgende Key:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\AppKey\[KeyName]

Onder de Key [KeyName] staat een nummer, dat is geassocieerd met een actie. In de volgende tabel staan de nummers met hun vertaling:

KeyName Commando Keyboard Button
16 APPCOMMAND_LAUNCH_MEDIA_SELECT Media player
15 APPCOMMAND_LAUNCH_MAIL Mail
8 APPCOMMAND_BROWSER_HOME Browser
18 APPCOMMAND_LAUNCH_APP2 Calculator
14 APPCOMMAND_MEDIA_PLAY_PAUSE Play/Pause
9 APPCOMMAND_VOLUME_DOWN Volume down
10 APPCOMMAND_VOLUME_UP Volume down
8 APPCOMMAND_VOLUME_MUTE Mute

Vervolgens kun je onder een Key ofwel een Association of een ShellExecute script aanmaken. In principe kan je om iTunes dan onder de MediaPlayer knop te stoppen, gewoon een ShellExecute key maken, die de iTunes applicatie gewoon opstart. Maar het is leuker als iTunes dan direct gaat spelen. Daarvoor zijn er scripts te vinden, die je dat makkelijker maken. Met die scripts kan je trouwens nog veel meer leuke dingen vanaf een commando line (of met de ShellExecutor) doen. Al met al krijg je dan een aantal Register Keys, die je tezamen in een Registration File (met de standaard extensie .reg)

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\explorer\AppKey]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\explorer\AppKey\15]
"Association"="mailto"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\explorer\AppKey\16]
"ShellExecute"="\"C:\\Program Files (x86)\\iTunes\\Scripts\\Play.vbs\""

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\explorer\AppKey\17]
"ShellExecute"="::{20D04FE0-3AEA-1069-A2D8-08002B30309D}"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\explorer\AppKey\18]
"ShellExecute"="calc.exe"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\explorer\AppKey\7]
"Association"="http"

Referenties, die ik bij dit artikel heb gebruikt:

Een meer volledige lijst van KeyName / Commando paren staat hieronder. Let op: het Logitech Internet 350 Keyboard heeft echter slechts de bovengenoemde 8 knoppen, dus de andere Commando’s kunnen op dat keyboard niet met 1 knop worden uitgevoerd.

KeyName Commando
1 Back (Internet browser)
2 Forward (Internet browser)
3 Refresh (Internet browser)
4 Stop (Internet browser)
5 Search
6 Favorites
7 WebHome
8 Mute volume
15 Mail
16 Media
17 My Computer
18 Calculato
24 Mute microphone
25 Lower microphone volume
26 Raise microphone volume
27 Help
28 Find
29 New
30 Open
31 Close
32 Save
33 Print
34 Undo
35 Redo
36 Copy
37 Cut
38 Paste
39 Reply
40 Forward (mail)
41 Send
42 Spelling checker
43 Toggle dictation and command/control
44 Toggle microphone
45 Corrections

09/11/2010

Cursus MVVM / MEF / SOLID voor Silverlight

Gearchiveerd onder: Publiek, Silverlight — Tags:, , , — Jan Keijzer @ 12:07

Op mijn zoektocht naar hoe je goed kan omgaan met de INotifyChanged interface, kwam ik een heel interessant artikel met de titel tegen waarin MVVM en MEF werden uitgelegd. Dat gaf mij aanleiding om hier verder op in te gaan en er mee te experimenteren. Daarbij kwam ik nog een aantal interessante artikelen tegen. Al met al ben ik hierdoor steeds meer enthousiast geworden om hiermee verder te gaan. En daarom wil ik dat in dit artikel een beetje vastleggen als een soort referentie voor in de toekomst.

Allereerst een aantal definities:

Afkorting Definitie Uitleg
MVVM Model View ViewModel Een architectuur, waarin het model, de view en een zogenaamde ViewModel van elkaar gescheiden zijn
MEF Managed Extensibility Framework Dit raamwerk verzorgt het detecteren van componenten en het vervolgens samenstellen van die componenten
SOLID Single responsibility, Open-closed, Liskov substitution, Interface segregation and Dependency inversion Een samenstelsel van een vijftal basis principe voor een goed OO design en goede OO programmeertechnieken

08/11/2010

Veilige login: hoe doe je dat?

Gearchiveerd onder: Datacommunicatie, HTTP, PHP, Publiek, Security, Silverlight — Jan Keijzer @ 19:45

Nu ik zover ben dat ik een inlog-scherm heb, wil ik ook graag een veilige manier om de login te laten plaatsvinden. En dat over een “gewone” HTTP verbinding, want ons huidig serverabonnement bij CSV-networks biedt geen mogelijkheid voor SSL (en dus ok niet voor HTTPS-certificaten). Daarvoor zouden we een eigen IP-adres moeten krijgen. En die kost (op dit moment) 14.50 euro per jaar extra. Gaan we nu even niet doen.

Simpele login voorbeelden

Daarom gekeken of er een andere manier is om veilig te kunnen inloggen. Nou, dat is toch nog best wel lastig. Er zijn wel allerlei login voorbeelden op internet te vinden, maar de meeste voorbeelden sturen of “plain-text” passwords van de client naar de server of (als er iets meer aan veiligheid wordt gedacht) MD5-gehashde passwords. Dat zijn toch geen veilige manieren om in te loggen, want iedereen, die kan sniffen, kan op die manier gewoon op het systeem komen. Een lijstje van deze oplossingen:

Veilige manier van inloggen

Na wat extra zoekwerk stuitte ik op de volgende pagina: PHP – Implementing Secure Login with PHP, JavaScript, and Sessions (without SSL). Een pagina, die vrij helder een Challenge-Response Authenticatie mechanisme beschrijft met PHP. Alleen wordt er ook een Javascript meegestuurd en dat wil ik natuurlijk niet. Dat zal door de Silverlight client moeten gebeuren. Maar goed, het principe zou ik wel kunnen gebruiken. Maar het grootste probleem met dit voorbeeld was dat dit voorbeeld alleen werkt als de passwords als “plain-text” in de database staan. Dat is wat ik ook niet wil. Maar daar is ook nog een oplossing voor. Die staat vermeldt in 1 van de commentaren. En is ook erg goed verwoordt in een artikel, waarin in dat commentaar naar wordt verwezen: You Want Salt With That?. Hierin wordt een Challenge-Response with Salt mechanisme besproken. Dat lijkt mij voor onze login de mooiste oplossing. Natuurlijk kan het altijd veiliger, maar deze methode is voor ons veilig genoeg. Dus nu aan de slag.

05/10/2009

Onze nieuwe website is live!

Gearchiveerd onder: Bedrijf, Marketing — Jan Keijzer @ 16:41

Vandaag hebben we onze nieuwe website live gezet. Een mooi nieuw design van onze vormgever: Rellebel Reclame. En we hebben ook flink aan de teksten geschreven. Ik ben er wel trots op. Maar een website is natuurlijk nooit af. Dus wie weet hoe onze site er over pakweg een maand of een jaar eruit ziet? In ieder geval kunnen we nu weer een tijdje vooruit nu we ook onze website in de nieuwe huisstijl hebben gezet.

Trouwens. De foto’s van mij en Rogier op onze “over ons” pagina zijn gemaakt door Jacqueline Louter van jaXpiX. Ook erg professioneel gedaan.

04/10/2009

NCSI – Sociale Innovatie werkt!

Gearchiveerd onder: Arbeidsproductiviteit, Innovatie, Personeel — Jan Keijzer @ 17:36

Afgelopen week contact gehad met het NCSI, het Nederlands Centrum voor Sociale Innovatie. Een erg inspirerend gesprek. Eindelijk een organisatie, die inziet dat innovatie niet alleen om technologie gaat. Maar dat mensen/ het personeel de motor achter vernieuwingen zijn. Ze ondersteunen een aantal leuke projecten, zoals een project waarbij medewerkers worden gestimuleerd om zelf roosters te maken. Dit in plaats van dat het roosters “van bovenaf” worden opgelegd. Daarmee is het voor de medewerkers veel makkelijker om hun rooster af te stemmen op hun eigen privé-leven. En het blijkt dat het ook nog eens tot een hogere productiviteit leidt. Prachtig om te merken dat het stimuleren van individuele verantwoordelijkheid van medewerkers daadwerkelijk tot betere prestaties van het personeel leidt.

Dit past tot heel erg in wat wij voorstaan met onze workshops. Laat medewerkers vooral zelf ontdekken hoe ze hun taak het beste kunnen uitvoeren. Er is zoveel kennis en ervaring op de werkvloer aanwezig. Het is echt zonde om die niet te benutten. En uiteindelijk zal dat toch de manier moeten zijn om de arbeidsproductiviteit in Nederland te verhogen. Naast alle technologische verbeteringen, die natuurlijk ook voor een hogere productiviteit kunnen zorgen. Maar laten we wel beide kanten, de techniek en de mens, in de innovatie meenemen. Fijn dat het NCSI hier een stimulans aan wil geven!

Google Wave – Echt samenwerken?

Gearchiveerd onder: Software, Software tools — Tags: — Jan Keijzer @ 17:15

Vandaag Google Wave ontdekt via DutchCowboys. Wat een mooie omgeving lijkt dit te zijn als je de instructie-video bekijkt. Ik kan mij voorstellen dat je op deze manier met een team medewerkers, heel eenvoudig samen kan. Zeker als je niet allemaal vanuit dezelfde locatie werkt. Maar zelfs ook als dat wel zo is, maar je bijvoorbeeld gezamenlijk een document wilt maken. Of je in een creatief proces wil bijhouden hoe een werkstuk tot stand komt. Ieder kan zijn eigen moment uitkiezen om dat stuk te bewerken. Of opmerkingen plaatsen.

Probleem op dit moment is wel dat het allemaal nog maar te zien is vanuit een marketing-perspectief. Het platform is nog niet openbaar toegankelijk, dus ik heb nog geen “hands-on” experience. En ja, dat is toch de lakmoes test. Er zelf mee gaan werken en kijken of het echt nuttig is. Maar op het eerste gezicht spreekt het mij erg aan. Dus even wacht tot half december 2009, de datum die op dit moment rondzingt als datum van de openbare release.

Oudere berichten »

Theme: Silver is the New Black. Blog op Wordpress.com.

Follow

Get every new post delivered to your Inbox.