// key_to_struct // Python version returns a string, but we use byte[] to get the same results public static byte[] KeyToStruct(RsaParameters key) { byte[] modLength = { 0x00, 0x00, 0x00, 0x80 }; var mod = key.Modulus; byte[] expLength = { 0x00, 0x00, 0x00, 0x03 }; var exponent = key.Exponent; return(DataTypeUtils.CombineBytes(modLength, mod, expLength, exponent)); }
// key_from_b64 // BitConverter has different endianness, hence the Reverse() public static RsaParameters KeyFromB64(string b64Key) { var decoded = Convert.FromBase64String(b64Key); var modLength = BitConverter.ToInt32(decoded.Take(4).Reverse().ToArray(), 0); var mod = decoded.Skip(4).Take(modLength).ToArray(); var expLength = BitConverter.ToInt32(decoded.Skip(modLength + 4).Take(4).Reverse().ToArray(), 0); var exponent = decoded.Skip(modLength + 8).Take(expLength).ToArray(); var rsaKeyInfo = new RsaParameters { Modulus = mod, Exponent = exponent }; return(rsaKeyInfo); }
// signature public static string CreateSignature(string email, string password, RsaParameters key) { var rsa = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithmNames.RsaOaepSha1); var keyBlob = CryptographicBuffer.DecodeFromBase64String(_b64KeyBlob); var publicKey = rsa.ImportPublicKey(keyBlob, CryptographicPublicKeyBlobType.Capi1PublicKey); byte[] prefix = { 0x00 }; var hashAlgorithm = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha1); var hash = hashAlgorithm.HashData(KeyToStruct(key).AsBuffer()).ToArray().Take(4).ToArray(); var encrypted = CryptographicEngine.Encrypt(publicKey, Encoding.UTF8.GetBytes(email + "\x00" + password).AsBuffer(), null).ToArray(); return(DataTypeUtils.UrlSafeBase64(DataTypeUtils.CombineBytes(prefix, hash, encrypted))); }