2017-02-18 3 views
2

문자열을 가져와 암호화 한 다음 해독하는 간단한 암호화 방법을 찾기 위해 온라인으로 사냥했습니다. 아이디어는 내가 계획 텍스트에 들어갈 수없는 URL에 ID가 필요하다는 것입니다.암호화 된 문자열에 결과에 슬래시 (/)가있어서 URL에 문제가 발생합니다.

은 내가 찾은 클래스는 대부분의 시간을 큰 workes, 그러나 때때로, 나는/그 안에있는 암호화 된 문자열로 끝날 : 당신이 상상할 수 있듯이 사용할 때

OSprnGR/0os4DQpQsa0gIg== 

, 즉 문제가 발생 URL. 그래서 문자열을 UrlEncode로하면 문제가 해결 될 것이라고 생각했습니다.

그렇지 않았습니다. 대신이의

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

을 : URL이 다음과 같습니다 경우에도

나는 여전히 같은 오류가

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

HTTP 오류 404.0 - 에게 당신이 찾고있는 리소스를 찾을 수 없음 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(); 
    } 
} 

편집 :

여기에 경로입니다 :

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

'HttpUtility.UrlEncode' 대신'HttpServerUtility.UrlTokenEncode'를 사용해 보셨나요? –

+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의 경로 부분에 특수 문자를 사용하지 말고 모든 문자열을 올바르게 URL로 보낼 수있는 쿼리 문자열로 지정해야합니다.

+1

그러나 OP는 이미 그들을 인코딩하는 URL로 슬래시를 대체합니다. – Evk

+0

내 OP에 편집 경로가 포함되어 있습니다.를 참조하십시오. 따라서 {id}를 {* id}로 바꾸면 문제가 해결됩니까? –

+0

.. 테스트. BRB –

1

문제를 해결하는 가장 좋은 방법은 아니지만 효과가 있을지 모릅니다. 이 선 후

: 다른 기호로

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

당신은 대체 할 수있는 슬래시 (/) (여러 문자) :

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

이제 중복 /없이 문자열을 얻을 것이다. 즉, 문자열 "abc/dce"을 인코딩했습니다. 교체 후 "abcItIsSlashReplacementdce"- /없이 - 것입니다.당신이 문자열을 디코딩 할 때

그럼 당신은 교체 반대한다 : - "abc/dce"를 한 후 디코딩 당신은 "abcItIsSlashReplacementdce" 얻을

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

을, 원래 복원합니다.

참고 : 대체 문자열을 선택하고 base64으로 인코딩 할 수 있습니다. 그러나 문자열은 길을 선택해야하므로 디코딩 후 /을 포함해서는 안됩니다.

+0

그래, 나는 같은 줄을 따라 생각하고 있었지만, 모든 상황에서 작동 할 것이라고/생각하는 것을 대체하기 위해 사용하는 것이 궁금했다. 의미 ... "대체"에 문자열이 필요합니다.이 문자열은 자연스럽게 Base64로 인코딩 된 문자열 안에서 끝나지 않습니다. –

+0

@CaseyCrookston, 당신은'replacement'를 선택해서'base64 '로 인코딩 할 수 있습니다 만, 인코딩 된 대체물은'/'이 없어야하고'/'를 대체해야합니다. 이 경우 하나의 base64를 다른 base64에 삽입합니다. –