Codifica Base64 non standard nel .Net Micro Framework

Come sappiamo, per poter accedere ai servizi Azure, in molti casi è prevista la SAS (Shared Access Signature) Authentication mediante l’invio di un token attraverso il quale otteniamo i diritti per poter eseguire specifiche operazioni.

Tale token si ottiene mediante la costruzione di una stringa contenente una serie di informazioni tra cui l’URI a cui accedere e la scadenza (expiry time) sulla quale calcolare un HMAC (Hash Massage Authentication Code) con SHA256. Il risultato di questa operazione di hashing viene codificato in Base64 ed il risultato ottenuto viene inserito all’interno del token (Shared Access Signature) con un opportuno formato.

L’obiettivo di questo post non è quello di descrivere precisamente la procedura per la determinazione del token ma di mettere in guardia chi utilizza le funzioni di conversione in Base64 messe a disposizione dal .Net Micro Framework.

Eseguendo i miei test con una board FEZ Spider per la connessione al Service Bus, ho riscontrato molte volte la condizione di accesso non autorizzato a causa di un token non correttamente calcolato. Eseguendo la stessa procedura sul PC, tutto funzionava correttamente. Come mai ?

Inizialmente ho pensato ad un errore nel calcolo della firma (HMAC) e solo dopo ho capito che c’era qualcosa che non andava nella codifica Base64.

Sono finalmente riuscito ad estrarre un caso di errore a seguito della firma rappresentata attraverso i seguenti bytes :

byte[] hmac = { 0x16, 0x01, 0x70, 0x76, 0xec, 0xc8, 0xdb, 0x01, 0xf0, 0x6a, 0x60, 0x9a, 0x89, 0x68, 0x6f, 0xef, 0x68, 0x9a, 0xad, 0x10, 0xe7, 0x92, 0x9b, 0xef, 0xfa, 0x10, 0x86, 0x24, 0xf1, 0x72, 0xa6, 0x69 };

Se proviamo a codificare in Base64 l’array di bytes suddetto con il metodo  Convert.ToBase64String(hmac) su PC, il risultato è il seguente :

FgFwduzI2wHwamCaiWhv72iarRDnkpvv+hCGJPFypmk=

Se proviamo ad eseguire la medesima operazione con il .Net Micro Framework, la codifica è la seguente :

FgFwduzI2wHwamCaiWhv72iarRDnkpvv!hCGJPFypmk=

In rosso ed in grassetto ho evidenziato la differenza tra le due codifiche ma … qual’è il motivo ?

Come sempre, la risposta è nell’implementazione nativa del .Net Micro Framework e questa volta nel file Convert.cs all’interno del quale si evincono due “alfabeti” per la codifica Base64 : l’alfabeto standard RFC4648 ed un alfabeto non standard.

 /// <summary>
 /// Conversion array from 6 bit of value into base64 encoded character.
 /// </summary>
 static char[] s_rgchBase64EncodingDefault = new char[]
 {
 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', /* 12 */
 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', /* 24 */
 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', /* 36 */
 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', /* 48 */
 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', /* 60 */
 '8', '9', '!', '*' /* 64 */
 };

 static char[] s_rgchBase64EncodingRFC4648 = new char[]
 {
 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', /* 12 */
 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', /* 24 */
 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', /* 36 */
 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', /* 48 */
 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', /* 60 */
 '8', '9', '+', '/' /* 64 */
 };

 static char[] s_rgchBase64Encoding = s_rgchBase64EncodingDefault;

Questi due alfabeti differiscono per gli ultimi due caratteri che sono “+” e “/” nel primo ma “!” e “*” nel secondo. A quanto pare il carattere “!” è relativo alla codifica Base64 nelle regular expressions mentre “*” é relativo alla medesima codifica nel privacy-enhanced mail.

Dal codice si evince che l’alfabeto di default (s_rgchBase64Encoding) che viene utilzzato non è quello standard !!

Come è possibile risolvere il problema ?

Per fortuna, la classe Convert fornisce la proprietà statica UseRFC4648Encoding che va impostata a true e grazie alla quale viene utilizzato l’alfabeto standard RFC4648 per ogni codifica Base64.

La mia opinione è che sarebbe opportuno invertire la logica in modo che la codifica di default sia quella standard e per questo motivo ho già aperto una issue sul sito ufficiale del .Net Micro Framework su CodePlex.

Voi cosa ne pensate ?

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s