//----- Microsoft PUBLICKEYBLOB format ---- public bool DecodeMSPublicKeyBlob(byte[] publickeyblob) { PUBKEYBLOBHEADERS pkheaders = new PUBKEYBLOBHEADERS(); int headerslength = Marshal.SizeOf(pkheaders); IntPtr buffer = Marshal.AllocHGlobal(headerslength); Marshal.Copy(publickeyblob, 0, buffer, headerslength); pkheaders = (PUBKEYBLOBHEADERS)Marshal.PtrToStructure(buffer, typeof(PUBKEYBLOBHEADERS)); Marshal.FreeHGlobal(buffer); //----- basic sanity check of PUBLICKEYBLOB fields ------------ if (pkheaders.bType != PUBLICKEYBLOB) { return(false); } if (pkheaders.bVersion != CUR_BLOB_VERSION) { return(false); } if (pkheaders.aiKeyAlg != CALG_RSA_KEYX && pkheaders.aiKeyAlg != CALG_RSA_SIGN) { return(false); } if (verbose) { Console.WriteLine("\n ---- PUBLICKEYBLOB headers ------"); Console.WriteLine(" btype {0}", pkheaders.bType); Console.WriteLine(" bversion {0}", pkheaders.bVersion); Console.WriteLine(" reserved {0}", pkheaders.reserved); Console.WriteLine(" aiKeyAlg 0x{0:x8}", pkheaders.aiKeyAlg); String magicstring = (new ASCIIEncoding()).GetString(BitConverter.GetBytes(pkheaders.magic)); Console.WriteLine(" magic 0x{0:x8} '{1}'", pkheaders.magic, magicstring); Console.WriteLine(" bitlen {0}", pkheaders.bitlen); Console.WriteLine(" pubexp {0}", pkheaders.pubexp); Console.WriteLine(" --------------------------------"); } //----- Get public key size in bits ------------- this.keySize = pkheaders.bitlen; //----- Get public exponent ------------- byte[] exponent = BitConverter.GetBytes(pkheaders.pubexp); //little-endian ordered Array.Reverse(exponent); //convert to big-endian order this.keyExponent = exponent; if (verbose) { showBytes("\nPublic key exponent (big-endian order):", exponent); } //----- Get modulus ------------- int modulusbytes = (int)pkheaders.bitlen / 8; byte[] modulus = new byte[modulusbytes]; try { Array.Copy(publickeyblob, headerslength, modulus, 0, modulusbytes); Array.Reverse(modulus); //convert from little to big-endian ordering. this.keyModulus = modulus; if (verbose) { showBytes("\nPublic key modulus (big-endian order):", modulus); } } catch (Exception) { Console.WriteLine("Problem getting modulus from publickeyblob"); return(false); } return(true); }
//----- Microsoft PUBLICKEYBLOB format ---- public bool DecodeMSPublicKeyBlob(byte[] publickeyblob) { PUBKEYBLOBHEADERS pkheaders = new PUBKEYBLOBHEADERS() ; int headerslength = Marshal.SizeOf(pkheaders); IntPtr buffer = Marshal.AllocHGlobal( headerslength); Marshal.Copy( publickeyblob, 0, buffer, headerslength ); pkheaders = (PUBKEYBLOBHEADERS) Marshal.PtrToStructure( buffer, typeof(PUBKEYBLOBHEADERS) ); Marshal.FreeHGlobal( buffer ); //----- basic sanity check of PUBLICKEYBLOB fields ------------ if(pkheaders.bType != PUBLICKEYBLOB) return false; if(pkheaders.bVersion != CUR_BLOB_VERSION) return false; if(pkheaders.aiKeyAlg != CALG_RSA_KEYX && pkheaders.aiKeyAlg != CALG_RSA_SIGN) return false; if(verbose) { Console.WriteLine("\n ---- PUBLICKEYBLOB headers ------"); Console.WriteLine(" btype {0}", pkheaders.bType); Console.WriteLine(" bversion {0}", pkheaders.bVersion); Console.WriteLine(" reserved {0}", pkheaders.reserved); Console.WriteLine(" aiKeyAlg 0x{0:x8}", pkheaders.aiKeyAlg); String magicstring = (new ASCIIEncoding()).GetString(BitConverter.GetBytes(pkheaders.magic)) ; Console.WriteLine(" magic 0x{0:x8} '{1}'", pkheaders.magic, magicstring); Console.WriteLine(" bitlen {0}", pkheaders.bitlen); Console.WriteLine(" pubexp {0}", pkheaders.pubexp); Console.WriteLine(" --------------------------------"); } //----- Get public key size in bits ------------- this.keySize = pkheaders.bitlen; //----- Get public exponent ------------- byte[] exponent = BitConverter.GetBytes(pkheaders.pubexp); //little-endian ordered Array.Reverse(exponent); //convert to big-endian order this.keyExponent = exponent; if(verbose) showBytes("\nPublic key exponent (big-endian order):", exponent); //----- Get modulus ------------- int modulusbytes = (int)pkheaders.bitlen/8 ; byte[] modulus = new byte[modulusbytes]; try { Array.Copy(publickeyblob, headerslength, modulus, 0, modulusbytes); Array.Reverse(modulus); //convert from little to big-endian ordering. this.keyModulus = modulus; if(verbose) showBytes("\nPublic key modulus (big-endian order):", modulus); } catch(Exception) { Console.WriteLine("Problem getting modulus from publickeyblob"); return false; } return true; }