Seperti judulnya, saya mendapatkan:
Panjang tidak valid untuk array karakter Base-64.
Saya telah membaca tentang masalah ini di sini dan sepertinya sarannya adalah untuk menyimpan ViewState dalam SQL jika ukurannya besar. Saya menggunakan wizard dengan banyak pengumpulan data sehingga kemungkinan ViewState saya besar. Tapi, sebelum saya beralih ke solusi "store-in-DB", mungkin seseorang dapat melihat dan memberi tahu saya jika saya memiliki pilihan lain?
Saya membuat email untuk pengiriman menggunakan metode di bawah ini:
public void SendEmailAddressVerificationEmail(string userName, string to)
{
string msg = "Please click on the link below or paste it into a browser to verify your email account.<BR><BR>" +
"<a href=\"" + _configuration.RootURL + "Accounts/VerifyEmail.aspx?a=" +
userName.Encrypt("verify") + "\">" +
_configuration.RootURL + "Accounts/VerifyEmail.aspx?a=" +
userName.Encrypt("verify") + "</a>";
SendEmail(to, "", "", "Account created! Email verification required.", msg);
}
Metode Enkripsi terlihat seperti ini:
public static string Encrypt(string clearText, string Password)
{
byte[] clearBytes = System.Text.Encoding.Unicode.GetBytes(clearText);
PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
byte[] encryptedData = Encrypt(clearBytes, pdb.GetBytes(32), pdb.GetBytes(16));
return Convert.ToBase64String(encryptedData);
}
Inilah tampilan HTML di hotmail:
Silakan klik tautan di bawah ini atau tempelkan ke browser untuk memverifikasi akun email Anda.
Di sisi penerima, halaman VerifyEmail.aspx.cs memiliki baris:
string username = Cryptography.Decrypt(_webContext.UserNameToVerify, "verify");
Berikut adalah pengambil untuk UserNameToVerify:
public string UserNameToVerify
{
get
{
return GetQueryStringValue("a").ToString();
}
}
Dan inilah metode GetQueryStringValue:
private static string GetQueryStringValue(string key)
{
return HttpContext.Current.Request.QueryString.Get(key);
}
Dan metode dekripsi terlihat seperti:
public static string Decrypt(string cipherText, string password)
{
**// THE ERROR IS THROWN HERE!!**
byte[] cipherBytes = Convert.FromBase64String(cipherText);
Dapatkah kesalahan ini diatasi dengan perbaikan kode atau haruskah saya menyimpan Kondisi Tampilan dalam database?
Replace
pernyataan lain . Encoding adalah coverall yang melindungi Anda.a = a + new string('=', (4 - a.Length % 4) % 4)
. Contoh untuk mendekode RFC 4648 URL-safe Base64 :public string base64urlDecode(string encoded) { return System.Text.Encoding.UTF8.GetString(System.Convert.FromBase64String(encoded.Replace("_","/").Replace("-","+") + new string('=', (4 - encoded.Length % 4) % 4))); }
UrlDecode
mana yang menghapus karakter. Terima kasih @MattEllenDugaan saya adalah bahwa Anda hanya perlu menyandikan URL string Base64 Anda saat Anda memasukkannya ke dalam string kueri.
Pengkodean Base64 menggunakan beberapa karakter yang harus disandikan jika mereka adalah bagian dari string kueri (yaitu
+
dan/
, dan mungkin=
juga). Jika string tidak dikodekan dengan benar maka Anda tidak akan dapat memecahkan kode itu dengan sukses di ujung lain, maka kesalahannya.Anda dapat menggunakan
HttpUtility.UrlEncode
metode ini untuk menyandikan string Base64 Anda:string msg = "Please click on the link below or paste it into a browser " + "to verify your email account.<br /><br /><a href=\"" + _configuration.RootURL + "Accounts/VerifyEmail.aspx?a=" + HttpUtility.UrlEncode(userName.Encrypt("verify")) + "\">" + _configuration.RootURL + "Accounts/VerifyEmail.aspx?a=" + HttpUtility.UrlEncode(userName.Encrypt("verify")) + "</a>";
sumber
=
karakter yang tertinggal .Saya belum cukup bereputasi untuk memberi suara positif atau berkomentar, tetapi jawaban LukeH tepat untuk saya.
Karena enkripsi AES adalah standar yang digunakan sekarang, ia menghasilkan string base64 (setidaknya semua implementasi enkripsi / dekripsi yang pernah saya lihat). String ini memiliki panjang kelipatan 4 (string.length% 4 = 0)
String yang saya dapatkan berisi + dan = di awal atau akhir, dan ketika Anda baru saja menggabungkannya menjadi string kueri URL, itu akan terlihat benar (misalnya, dalam email yang Anda buat), tetapi ketika tautan diikuti dan tautan Halaman .NET menerimanya dan memasukkannya ke this.Page.Request.QueryString, karakter khusus tersebut akan hilang dan panjang string Anda tidak akan menjadi kelipatan 4.
Karena adalah karakter khusus di FRONT string (mis .: +), serta = di akhir, Anda tidak bisa hanya menambahkan beberapa = untuk membuat perbedaan saat Anda mengubah teks sandi dengan cara yang tidak tidak cocok dengan apa yang sebenarnya ada di string kueri asli.
Jadi, membungkus teks sandi dengan HttpUtility.URLEncode (bukan HtmlEncode) mengubah karakter non-alfanumerik dengan cara yang memastikan .NET mem-parsingnya kembali ke keadaan semula ketika diintepretasikan ke dalam kumpulan querystring.
Hal baiknya adalah, kita hanya perlu melakukan URLEncode saat membuat querystring untuk URL. Di sisi masuk, itu secara otomatis diterjemahkan kembali ke nilai string asli.
Berikut beberapa contoh kode
string cryptostring = MyAESEncrypt(MySecretString); string URL = WebFunctions.ToAbsoluteUrl("~/ResetPassword.aspx?RPC=" + HttpUtility.UrlEncode(cryptostring));
sumber
Tebakan awal saya tanpa mengetahui datanya adalah bahwa UserNameToVerify bukanlah kelipatan 4 panjangnya. Lihat FromBase64String di msdn .
// Ok byte[] b1 = Convert.FromBase64String("CoolDude"); // Exception byte[] b2 = Convert.FromBase64String("MyMan");
sumber
String terenkripsi memiliki dua karakter khusus,
+
dan=
.Tanda '+' memberikan kesalahan, jadi solusi di bawah ini bekerja dengan baik:
//replace + sign encryted_string = encryted_string.Replace("+", "%2b"); //`%2b` is HTTP encoded string for **+** sign
ATAU
//encode special charactes encryted_string = HttpUtility.UrlEncode(encryted_string); //then pass it to the decryption process ...
sumber
string stringToDecrypt = CypherText.Replace(" ", "+"); int len = stringToDecrypt.Length; byte[] inputByteArray = Convert.FromBase64String(stringToDecrypt);
sumber