Je veux obscorer un paramètre de chaîne de requête dans ASP.NET. Le site aura un volume de demande élevé. L'algorithme ne devrait donc pas être trop lent.
Mon problème est que tous les algorithmes que j'ai trouvés entraînent des caractères non désirés (comme + / =) p>
ici est un exemple de ce que je veux réaliser: p> à p> le paramètre obscurcier ne doit inclure que Je sais que je peux chiffrer à l'aide de base64, mais cela générera des caractères indésirables tels que aucune idée de l'algorithme peut être utilisé? p> update: strong>
Je suis au courant de l'urlencodage, je veux éviter de coder la chaîne.
parce que cela générera des charaters comme% F2 ou% B2 dans l'URL. P> P> / code> ou = < / code> ou + code>. p>
6 Réponses :
Avez-vous essayé CODING URL Votre Texte de la chaîne de requête? Il fait partie du HTTTPutilité classe qui: p>
fournit des méthodes d'encodage et Décoder les URL lors du traitement de la bande Demandes. P> blockQuote>
et devrait vous permettre de transmettre votre texte codé de base64 dans la chaîne de requête. P>
Thx pour réponse, je ne veux tout simplement pas de caractères comme% F2 ou% B2 dans l'URL.
Vous pouvez utiliser httpserverutilité.urltokenencode a > et httpserverutilité.urltokendeCode P >
Encode utilise le codage de base64, mais remplace les caractères hostiles de l'URL. P>
Il y a une réponse similaire dans un précédent donc question . Voir la réponse acceptée. P>
Faites votre cryptage, puis utilisez HTTPSERVERUILLITAIRE.URLTOXENCODE () pour encoder le tableau d'octets. P>
Désolé, j'ai raté l'exigence supplémentaire que tous les personnages devaient être alphanumériques. Si ce n'est pas une exigence absolue, il est prudent d'inclure le "-" et "_" dans un paramètre d'URL ...
Voici un exemple de travail que j'ai mis en place à partir de quelques exemples différents qui prend un identifiant entier et la convertit en une chaîne cryptée formatée hexidécimale. Cette chaîne cryptée ne doit pas inclure des caractères hostiles de l'URL et n'inclut pas les caractères échappés non plus.
Voici toute l'application de console de travail. Veuillez noter que c'est un prototype et sans aucun doute pas pour la production - cela illustre simplement une solution et doit certainement être refactored. P>
Lorsque vous exécutez le code, votre sortie doit être ceci: P>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;
namespace ConsoleApplication1
{
class Program2
{
static void Main(string[] args)
{
int theId = 1234; //the ID that's being manipulated
byte[] byteArray; //the byte array that stores
//convert the ID to an encrypted string using a Crypto helper class
string encryptedString = Crypto.EncryptStringAES(theId.ToString(), "mysecret");
Console.WriteLine("{0} get encrypted as {1}", theId.ToString(), encryptedString);
//convert the encrypted string to byte array
byteArray = ASCIIEncoding.Default.GetBytes(encryptedString);
StringBuilder result = new StringBuilder();
//convert each byte to hex and append to a stringbuilder
foreach (byte outputByte in byteArray)
{
result.Append(outputByte.ToString("x2"));
}
Console.WriteLine("{0} encrypted is this in hex {1}", encryptedString, result.ToString());
//now reverse the process, and start with converting each char in string to byte
int stringLength = result.Length;
byte[] bytes = new byte[stringLength / 2];
for (int i = 0; i < stringLength; i += 2)
{
bytes[i / 2] = System.Convert.ToByte(result.ToString().Substring(i, 2), 16);
}
//convert the byte array to de-"hexed" string
string dehexedString = ASCIIEncoding.Default.GetString(bytes);
Console.WriteLine("{0} gets dehexed as {1}", result, dehexedString);
//decrypt the de-"hexed" string using Crypto helper class
string decryptedString = Crypto.DecryptStringAES(dehexedString, "mysecret");
Console.WriteLine("{0} got decrypted as {1}", dehexedString, decryptedString);
Console.ReadLine();
}
}
public class Crypto
{
private static byte[] _salt = Encoding.ASCII.GetBytes("o6806642kbM7c5");
/// <summary>
/// Encrypt the given string using AES. The string can be decrypted using
/// DecryptStringAES(). The sharedSecret parameters must match.
/// </summary>
/// <param name="plainText">The text to encrypt.</param>
/// <param name="sharedSecret">A password used to generate a key for encryption.</param>
public static string EncryptStringAES(string plainText, string sharedSecret)
{
if (string.IsNullOrEmpty(plainText))
throw new ArgumentNullException("plainText");
if (string.IsNullOrEmpty(sharedSecret))
throw new ArgumentNullException("sharedSecret");
string outStr = null; // Encrypted string to return
RijndaelManaged aesAlg = null; // RijndaelManaged object used to encrypt the data.
try
{
// generate the key from the shared secret and the salt
Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(sharedSecret, _salt);
// Create a RijndaelManaged object
// with the specified key and IV.
aesAlg = new RijndaelManaged();
aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8);
aesAlg.IV = key.GetBytes(aesAlg.BlockSize / 8);
// Create a decrytor to perform the stream transform.
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
// Create the streams used for encryption.
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
//Write all data to the stream.
swEncrypt.Write(plainText);
}
}
outStr = Convert.ToBase64String(msEncrypt.ToArray());
}
}
finally
{
// Clear the RijndaelManaged object.
if (aesAlg != null)
aesAlg.Clear();
}
// Return the encrypted bytes from the memory stream.
return outStr;
}
/// <summary>
/// Decrypt the given string. Assumes the string was encrypted using
/// EncryptStringAES(), using an identical sharedSecret.
/// </summary>
/// <param name="cipherText">The text to decrypt.</param>
/// <param name="sharedSecret">A password used to generate a key for decryption.</param>
public static string DecryptStringAES(string cipherText, string sharedSecret)
{
if (string.IsNullOrEmpty(cipherText))
throw new ArgumentNullException("cipherText");
if (string.IsNullOrEmpty(sharedSecret))
throw new ArgumentNullException("sharedSecret");
// Declare the RijndaelManaged object
// used to decrypt the data.
RijndaelManaged aesAlg = null;
// Declare the string used to hold
// the decrypted text.
string plaintext = null;
try
{
// generate the key from the shared secret and the salt
Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(sharedSecret, _salt);
// Create a RijndaelManaged object
// with the specified key and IV.
aesAlg = new RijndaelManaged();
aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8);
aesAlg.IV = key.GetBytes(aesAlg.BlockSize / 8);
// Create a decrytor to perform the stream transform.
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
// Create the streams used for decryption.
byte[] bytes = Convert.FromBase64String(cipherText);
using (MemoryStream msDecrypt = new MemoryStream(bytes))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
plaintext = srDecrypt.ReadToEnd();
}
}
}
finally
{
// Clear the RijndaelManaged object.
if (aesAlg != null)
aesAlg.Clear();
}
return plaintext;
}
}
}
Content que ça marche! Malheureusement, il est long en raison des caractères alphanumériques limités pouvant être utilisés. :)
Le problème d'obscurcissement de l'identifiant, c'est que vous avez besoin d'un moyen de déconcerter. Cela nécessite soit:
alternativement, gardez l'identifiant clair, mais utilisez également un chèque. p> plus la valeur est élevée pour réduire, plus le résultat est plus petit (jusqu'à ce que à 6, il continue à produire la chaîne vide). Une valeur faible (ou 0) donne une meilleure sécurité, au coût d'une URI plus longue. P> la chaîne avec ce qui précède, un dans le gestionnaire qui chercherait ce que 15 est , nous faisons la même chose, et si le résultat est différent de 05469B1E, nous pouvons renvoyer une 403 interdite ou sans doute plus raisonnable 404 non trouvée (sur la base que nous avons reçu une URI que dans son ensemble n'identifie rien ). P> p> "Il s'agit d'un sel arbitraire" code> doit être secret pour la meilleure sécurité. Il peut être codé dur dans certaines utilisations, mais voudrait être obtenu à partir d'une source sécurisée pour d'autres. P> ID code> de 15 et un réduit < / code> de 3 produit un résultat de 05469B1E. Nous pouvons ensuite utiliser ceci comme suit: p> www.domain.com/?id=15&chk=05469b1e code> p>
Vous pouvez utiliser Triple des pour coder la valeur à l'aide d'un chiffrement de bloc Narow. La sortie doit être quelque chose comme ceci: P> Number to encode = 1795789891.
Key to encode with is 6c90323644c841a00d40d4407e23dbb2ab56530e1a4bae43.
The encoded value is 731fceec2af2fcc2790883f2b79e9a01.
Successfully decoded the encoded value.
The decoded result is 1795789891.
Merci de réponse, a fière allure, je vais essayer d'essayer. une idée de la performance? Est-ce une grande surcharge?
Cela ne devrait pas aboutir à des frais généraux très importants. Si vous utilisez HTTPS, cette opération exacte est effectuée quelques centaines de fois pour cela pour une seule page HTML, de sorte que cela devrait être trivial.
Est-ce un incontournable d'utiliser dangereux et des pointeurs? ceux ne sont pas vraiment sur mon menu quotidien :)
Non, vous pouvez supprimer les pointeurs, mais vous devez alors écrire une boucle pour copier l'entier dans / depuis la matrice d'octets.
@Lunatic, @sharru: Ni une boucle ni un bloc dangereux n'est nécessaire , system.bitconverter code> fera très bien le truc.
Cool. N'a pas vu ça avant! Merci!
Pourquoi voulez-vous chiffrer cette valeur? Éviter de deviner ou d'obscurcer?
Base64 est codé et codage n'est pas un cryptage
@Sharru: Je pense que vous voulez probablement dire "obscurcissement" plutôt que "cryptage". Je vous suggère de modifier vos tags, titre et vos questions en conséquence. Si vous voulez vraiment crypter, la base64 n'est pas la façon de le faire.
Quelle sorte d'abus, spécifiquement, essayez-vous d'éviter?
@Aillyn: Je pense que Sharru signifie un codage supplémentaire des paramètres cryptés pour éliminer les caractères indésirables.
Pourquoi la restriction sur les personnages de la valeur obscurcie? "Sent" hack-ish.
J'essaie simplement d'éviter la saisie de l'utilisateur dans ID = 999, puis ID = 1000. et je veux que les URL soient "propres" (juste des lettres et des chiffres). N'est-ce pas possible?
Ajouté une autre réponse pouvant aborder ce que vous recherchez
On dirait que tu es trop en pensant un petit détail. Pouvez-vous fournir un meilleur exemple de pourquoi vous avez besoin de ces contraintes apparemment arbitraires?
Si vous comptez sur l'obfuscation pour prévenir les abus, vous avez déjà perdu. Au lieu de cela, concevez votre application mieux - par exemple, en appliquant des contrôles d'accès, les gens ne peuvent donc pas accéder à ce qu'ils ne devraient pas être en mesure de, ou en attribuant un GUID à chaque enregistrement afin de disposer d'un identifiant long et difficile à deviner.