ich mit wenig Erfolg in den Hafen über die Google-Code bin versucht, ein sicheres Zeichen für ihre Captcha zu erzeugen (https://github.com/google/recaptcha-java/blob/master/appengine/src/main/java/com/google/recaptcha/STokenUtils.java):Porting Java Verschlüsselungsroutine zu C#
Das Original-Dienstprogramm hat die folgenden:
private static final String CIPHER_INSTANCE_NAME = "AES/ECB/PKCS5Padding";
private static String encryptAes(String input, String siteSecret) {
try {
SecretKeySpec secretKey = getKey(siteSecret);
Cipher cipher = Cipher.getInstance(CIPHER_INSTANCE_NAME);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
return BaseEncoding.base64Url().omitPadding().encode(cipher.doFinal(input.getBytes("UTF-8")));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static SecretKeySpec getKey(String siteSecret){
try {
byte[] key = siteSecret.getBytes("UTF-8");
key = Arrays.copyOf(MessageDigest.getInstance("SHA").digest(key), 16);
return new SecretKeySpec(key, "AES");
} catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
public static void main(String [] args) throws Exception {
//Hard coded the following to get a repeatable result
String siteSecret = "12345678";
String jsonToken = "{'session_id':'abf52ca5-9d87-4061-b109-334abb7e637a','ts_ms':1445705791480}";
System.out.println(" json token: " + jsonToken);
System.out.println(" siteSecret: " + siteSecret);
System.out.println(" Encrypted stoken: " + encryptAes(jsonToken, siteSecret));
Angesichts der Werte, die ich fest codierte, bekomme ich Irez-rWkCEqnsiRLWfol0IXQu1JPs3qL_G_9HfUViMG9u4XhffHqAyju6SRvMhFS86czHX9s1tbzd6B15r1vmY6s5S8odXT-ZE9A-y1lHns"
zurück als mein verschlüsseltes Token.
Meine Java und Crypto Fähigkeiten sind mehr als ein bisschen eingerostet, und es gibt nicht immer direkte Analoga in C#. Ich versuchte encrypeAes()
und getKey()
mit folgenden zu verschmelzen, was nicht korrekt ist:
public static string EncryptText(string PlainText, string siteSecret)
{
using (RijndaelManaged aes = new RijndaelManaged())
{
aes.Mode = CipherMode.ECB;
aes.Padding = PaddingMode.PKCS7;
var bytes = Encoding.UTF8.GetBytes(siteSecret);
SHA1 sha1 = SHA1.Create();
var shaKey = sha1.ComputeHash(bytes);
byte[] targetArray = new byte[16];
Array.Copy(shaKey, targetArray, 16);
aes.Key = targetArray;
ICryptoTransform encrypto = aes.CreateEncryptor();
byte[] plainTextByte = ASCIIEncoding.UTF8.GetBytes(PlainText);
byte[] CipherText = encrypto.TransformFinalBlock(plainTextByte, 0, plainTextByte.Length);
return HttpServerUtility.UrlTokenEncode(CipherText); //Equivalent to java's BaseEncoding.base64Url()?
}
}
Die C# Version erzeugt den falschen Wert von: Ye+fySvneVUZJXth67+Si/e8fBUV4Sxs7wEXVDEOJjBMHl1encvt65gGIj8CiFzBGp5uUgKYJZCuQ4rc964vZigjlrJ/430LgYcathLLd9U=
Implementiert SHA1-Hashing, noch keine Freude. –
Sie könnten versuchen, ['AesManaged'] (https://msdn.microsoft.com/en-us/library/system.security.cryptography.aesmanaged%28v=vs.100%29.aspx) anstelle von' RijndaelManaged' zu verwenden (die standardmäßig eine andere Schlüsselgröße hat und daher nicht der * Standard * AES ist), um den Java-Part 'CIPHER_INSTANCE_NAME =" AES/ECB/PKCS5Padding "zu finden und [' Convert.ToBase64String'] zu verwenden (https: // msdn.microsoft.com/en-us/library/dhx0d524%28v=vs.110%29.aspx) anstelle von 'HttpServerUtility.UrlTokenEncode ...'. – pasty
Aktualisiert, um C# -Ausgabe einzuschließen. @pasty Ich habe auf "AESManaged" aktualisiert, bin mir aber nicht sicher, wie ich mich an den Chiffre-Namen anpassen würde. Ich habe mich für "PaddingMode.PKCS7" pro http://blog.zebsadiq.com/post/AESCBCPKCS5Padding-EncryptionDecryption-in-C.aspx entschieden, aber ich gebe zu, dass ich mit mir herumfummle. Der Wechsel zu 'Convert.ToBase64String' hatte keine Auswirkungen auf das Ergebnis. Ich habe mich für 'HttpServerUtility.UrlTokenEncode' entschieden, da es der Basis BaseEncoding.base64Url() von Java am nächsten kam. –