2017-02-18 3 views
2

Я охотился в Интернете, чтобы найти простой метод шифрования, который бы взял строку, зашифровал ее и расшифровал. Идея состоит в том, что у меня есть идентификаторы, которые мне нужны в URL-адресе, который не может быть в тексте плана.Зашифрованная строка имеет в результате косую черту (/), которая вызывает проблемы с URL-адресом.

Класс я нашел workes большой большую часть времени, но иногда, я в конечном итоге с зашифрованной строки, которая имеет/в нем:

OSprnGR/0os4DQpQsa0gIg== 

Как вы можете себе представить, что вызывает проблемы при использовании в URL. Поэтому я подумал, что если я просто UrlEncode строки, это решит проблему.

Это не так.

Я все еще получаю ту же ошибку, даже если URL выглядит следующим образом:

http://localhost:54471/BrokerDashboard/BuyingLeads/LeadView/OSprnGR%2f0os4DQpQsa0gIg%3d%3d 

Вместо этого:

http://localhost:54471/BrokerDashboard/BuyingLeads/LeadView/OSprnGR/0os4DQpQsa0gIg== 

Ошибка HTTP 404.0 - Not Found Ресурс, который вы ищете for был удален, изменилось его имя или временно недоступно.

Вот класс, я использую:

public static class Encryption 
{ 
    public static string keyString { get { return "6C3A231C-57B2-4BA0-AFD6-306098234B11"; } } 
    private static byte[] salt = Encoding.ASCII.GetBytes("somerandomstuff"); 

    public static string Encrypt(string plainText) 
    { 
     Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(keyString, salt); 
     MemoryStream ms = new MemoryStream(); 
     StreamWriter sw = new StreamWriter(new CryptoStream(ms, new RijndaelManaged().CreateEncryptor(key.GetBytes(32), key.GetBytes(16)), CryptoStreamMode.Write)); 
     sw.Write(plainText); 
     sw.Close(); 
     ms.Close(); 
     string beforeUrlEncoded = Convert.ToBase64String(ms.ToArray()); 
     string afterUrlEndcoded = HttpUtility.UrlEncode(beforeUrlEncoded); 
     return afterUrlEndcoded; 
    } 

    public static string Decrypt(string encrypted) 
    { 
     //string urlDecoded = HttpUtility.UrlDecode(encrypted); // <--- Turns out you don't need this 
     Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(keyString, salt); 
     ICryptoTransform d = new RijndaelManaged().CreateDecryptor(key.GetBytes(32), key.GetBytes(16)); 
     byte[] bytes = Convert.FromBase64String(encrypted); 
     return new StreamReader(new CryptoStream(new MemoryStream(bytes), d, CryptoStreamMode.Read)).ReadToEnd(); 
    } 
} 

EDIT:

Вот маршрут:

routes.MapRoute(
    name: "BrokerLead", 
    url: "BrokerDashboard/BuyingLeads/LeadView/{id}" 
); 
+1

Вы пытались использовать 'HttpServerUtility.UrlTokenEncode' вместо' HttpUtility.UrlEncode'? –

+1

Просто подтверждая, что вы уже читали статью в Википедии о bade64 и отказались от возможности использовать безопасную версию url. Я бы рекомендовал уточнить это в сообщении. –

+0

@AlexeiLevenkov - У .NET есть возможность использовать кодировку URL Safe Base64? –

ответ

6

/ символ зарезервирован и не могут быть использованы в участок пути. Если это последний сегмент вашего URL можно использовать следующий маршрут, чтобы сделать его работу (обратите внимание на {*id} сегмент):

routes.MapRoute(
    name: "Default", 
    url: "{controller}/{action}/{*id}", 
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
); 

Другой подход состоит в замене этого персонажа с какой-то другой, когда шифрование/дешифрование, но в целом вам следует избегать специальных символов в части пути URL-адреса и просто поместить их в строку запроса, где вы можете правильно кодировать все кодировки.

+1

Но OP уже заменяет косую червь, кодируя их. – Evk

+0

см. Редактирование моего OP, который включает в себя маршрут. Таким образом, замена {id} на {* id} решит проблему? –

+0

.. тестирование. BRB –

1

Возможно, это не лучший способ решить проблему, но она должна работать.

После этой линии:

string beforeUrlEncoded = Convert.ToBase64String(ms.ToArray()); 

Вы можете заменить косые (/) некоторыми другими символами (несколько символов):

string replacement = "ItIsSlashReplacement"; 
beforeUrlEncoded = beforeUrlEncoded.Replace("/", replacement); 

Теперь вы получите строку без избыточной /. I.e, вы закодировали строку "abc/dce". После замены у вас будет "abcItIsSlashReplacementdce" - без /.

Затем, когда вам нужно декодировать строку, которую вы должны поменять местами замены:

string replacement = "ItIsSlashReplacement"; 
string originalEncodedString = stringWithReplacement.Replace(replacement, "/"); 

Вы получаете "abcItIsSlashReplacementdce", восстановить оригинал - "abc/dce", а затем расшифровать его.

ПРИМЕЧАНИЕ: Вы можете выбрать как замену некоторую строку и закодировать ее до base64. Но строка должна быть выбрана так, чтобы после декодирования она не содержала /.

+0

Да, я думал по тем же линиям, но задавался вопросом, что использовать, чтобы заменить /, что я знаю, будет работать в любой ситуации. Значение ... Мне нужна строка в «замене», которая, естественно, не попадет в кодировку Base64. –

+0

@CaseyCrookston, вы можете выбрать «замену» и закодировать его на «base64», но закодированная замена должна быть без '/', а затем заменить '/'. В этом случае вы вставляете один base64 внутри другого. –

Смежные вопросы