2010-01-19 11 views
19

के बीच संगत मैं कैसे सी # में एन्क्रिप्शन, और Android के लिए एक जोड़े को ऐसा करने के लिए उदाहरण के बहुत सारे मिल गया है, लेकिन मैं विशेष रूप से एक तरह से एईएस, TripleDES, आदि की तरह कुछ का उपयोग कर एनक्रिप्ट करने को संभालने के लिए (के लिए देख रहा हूँ ।) एंड्रॉइड से, और आखिरकार हवा में सी # में डिक्रिप्ट किया जा रहा है। मुझे एंड्रॉइड में example for encoding AES और सी # में encoding/decoding AES मिला लेकिन मुझे यकीन नहीं है कि ये संगत हैं (सी # को एक चतुर्थ की आवश्यकता है, एंड्रॉइड उदाहरण में इसके लिए कुछ भी निर्दिष्ट नहीं है)। साथ ही, HTTP (बेस 64?) पर ट्रांसमिशन के लिए एन्क्रिप्टेड स्ट्रिंग एन्कोडिंग के एक अच्छे तरीके पर एक सिफारिश उपयोगी होगी। धन्यवाद।एन्क्रिप्शन Android और सी #

+0

लिंक मर चुका है। क्या आप एंड्रॉइड के लिए इस्तेमाल किए गए कोड स्निपेट को जोड़ सकते हैं? –

उत्तर

38

http://oogifu.blogspot.com/2009/01/aes-in-java-and-c.html से कुछ मदद मिल गया।

package com.neocodenetworks.smsfwd; 

import java.security.*; 
import javax.crypto.*; 
import javax.crypto.spec.*; 
import android.util.Log; 

public class Crypto { 
    public static final String TAG = "smsfwd"; 

    private static Cipher aesCipher; 
    private static SecretKey secretKey; 
    private static IvParameterSpec ivParameterSpec; 

    private static String CIPHER_TRANSFORMATION = "AES/CBC/PKCS5Padding"; 
    private static String CIPHER_ALGORITHM = "AES"; 
    // Replace me with a 16-byte key, share between Java and C# 
    private static byte[] rawSecretKey = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 

    private static String MESSAGEDIGEST_ALGORITHM = "MD5"; 

    public Crypto(String passphrase) { 
     byte[] passwordKey = encodeDigest(passphrase); 

     try { 
      aesCipher = Cipher.getInstance(CIPHER_TRANSFORMATION); 
     } catch (NoSuchAlgorithmException e) { 
      Log.e(TAG, "No such algorithm " + CIPHER_ALGORITHM, e); 
     } catch (NoSuchPaddingException e) { 
      Log.e(TAG, "No such padding PKCS5", e); 
     } 

     secretKey = new SecretKeySpec(passwordKey, CIPHER_ALGORITHM); 
     ivParameterSpec = new IvParameterSpec(rawSecretKey); 
    } 

    public String encryptAsBase64(byte[] clearData) { 
     byte[] encryptedData = encrypt(clearData); 
     return net.iharder.base64.Base64.encodeBytes(encryptedData); 
    } 

    public byte[] encrypt(byte[] clearData) { 
     try { 
      aesCipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec); 
     } catch (InvalidKeyException e) { 
      Log.e(TAG, "Invalid key", e); 
      return null; 
     } catch (InvalidAlgorithmParameterException e) { 
      Log.e(TAG, "Invalid algorithm " + CIPHER_ALGORITHM, e); 
      return null; 
     } 

     byte[] encryptedData; 
     try { 
      encryptedData = aesCipher.doFinal(clearData); 
     } catch (IllegalBlockSizeException e) { 
      Log.e(TAG, "Illegal block size", e); 
      return null; 
     } catch (BadPaddingException e) { 
      Log.e(TAG, "Bad padding", e); 
      return null; 
     } 
     return encryptedData; 
    } 

    private byte[] encodeDigest(String text) { 
     MessageDigest digest; 
     try { 
      digest = MessageDigest.getInstance(MESSAGEDIGEST_ALGORITHM); 
      return digest.digest(text.getBytes()); 
     } catch (NoSuchAlgorithmException e) { 
      Log.e(TAG, "No such algorithm " + MESSAGEDIGEST_ALGORITHM, e); 
     } 

     return null; 
    } 
} 

मैं बेस 64 एन्कोडिंग के लिए http://iharder.sourceforge.net/current/java/base64/ प्रयोग किया है:

यहाँ मेरी जावा वर्ग है।

यहाँ मेरी सी # वर्ग है:

using System; 
using System.Text; 
using System.Security.Cryptography; 

namespace smsfwdClient 
{ 
    public class Crypto 
    { 
     private ICryptoTransform rijndaelDecryptor; 
     // Replace me with a 16-byte key, share between Java and C# 
     private static byte[] rawSecretKey = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 

     public Crypto(string passphrase) 
     { 
      byte[] passwordKey = encodeDigest(passphrase); 
      RijndaelManaged rijndael = new RijndaelManaged(); 
      rijndaelDecryptor = rijndael.CreateDecryptor(passwordKey, rawSecretKey); 
     } 

     public string Decrypt(byte[] encryptedData) 
     { 
      byte[] newClearData = rijndaelDecryptor.TransformFinalBlock(encryptedData, 0, encryptedData.Length); 
      return Encoding.ASCII.GetString(newClearData); 
     } 

     public string DecryptFromBase64(string encryptedBase64) 
     { 
      return Decrypt(Convert.FromBase64String(encryptedBase64)); 
     } 

     private byte[] encodeDigest(string text) 
     { 
      MD5CryptoServiceProvider x = new System.Security.Cryptography.MD5CryptoServiceProvider(); 
      byte[] data = Encoding.ASCII.GetBytes(text); 
      return x.ComputeHash(data); 
     } 
    } 
} 

मैं वास्तव में इस किसी और में मदद करता है उम्मीद है!

+7

हाँ ... मुझे प्यार है जब लोग मेरे तकनीकी प्रश्न का जवाब देते हैं "ओह, आपको ऐसा करना चाहिए" या "ओह, आपको यह करना चाहिए"। व्यावहारिक होने और अपनी कक्षा कार्यान्वयन छोड़ने के लिए धन्यवाद। – kape123

+0

मैंने अपनी फ़ाइल सामग्री को अपने जावा कोड से एन्क्रिप्ट किया है और एन्क्रिप्टेड सामग्री को एन्क्रिप्टेड.txt में सहेजा है। अब मैं इसे इस कमांड का उपयोग करके openssl टूल के साथ डिक्रिप्ट करना चाहता हूं: openssl enc -d -a -p -aes-256-cbc -salt -in एन्क्रिप्टेड.txt -out decrypted.txt -pass पास: myPassword लेकिन मुझे त्रुटि मिलती है: बुरा जादू संख्या। कोई विचार क्या गलत है? यहां तक ​​कि यदि मैं कमांड से -ल्ट पैरामीटर को हटा देता हूं, तो भी मुझे एक ही त्रुटि मिल रही है। – uerceg

+0

@Uerceg: आप इसके लिए एक नया प्रश्न शुरू करना चाहते हैं। यह समाधान ओपनएसएसएल का उपयोग नहीं करता है इसलिए मुझे काम करने की उम्मीद नहीं है। – Jess

1

हाँ यह ठीक होना चाहिए, जब तक कि हम keysize एक ही है - 128 बिट एईएस और सही ब्लॉक सिफर मोड (सीबीसी)। आप पैडिंग के साथ मुद्दों में भाग सकते हैं, लेकिन यह हल करने के लिए काफी आसान होना चाहिए। मैं हाल ही में जावा और पायथन के साथ इन मुद्दों में भाग गया, लेकिन अंत में सबकुछ काम कर रहा था। एन्कोडिंग के लिए बेस 64 HTTP पर ठीक होना चाहिए। सौभाग्य!

1

यदि आप दोनों सिरों पर एक ही सिफर (जैसे एईएस) और मोड (जैसे सीटीआर, सीएफबी, सीसीएम, आदि) को सही ढंग से कार्यान्वित करते हैं, तो एक छोर से सिफरटेक्स्ट को दूसरी तरफ प्लेटफॉर्म पर ध्यान दिए बिना डिक्रिप्ट किया जा सकता है।

एंड्रॉयड उदाहरण आप से जुड़ा हुआ अपने उद्देश्यों के लिए सुरक्षित नहीं है ईसीबी मोड का उपयोग प्रतीत होता है, और इस तरह। यह महत्वपूर्ण है कि आप चुनने वाले ब्लॉक मोड के प्रभावों को समझें। इस स्तर पर क्रिप्टो को गलत करना बहुत आसान है, जिसके परिणामस्वरूप एक प्रणाली है जो उतनी सुरक्षित नहीं है जितनी आपको लगता है।

संपादित करें: मुझे लगता है कि वापस ले, यह ईसीबी का उपयोग नहीं कर रहा है, लेकिन जिस तरह से यह उत्पन्न चतुर्थ व्यावहारिक नहीं है। किसी भी मामले में, ब्लॉक मोड के प्रभाव को समझने के बारे में मेरा मुद्दा खड़ा है।

आप इस wikipedia article के साथ शुरू कर सकते हैं। ब्रूस श्नीयर की पुस्तक 'Practical Cryptography' क्रिप्टोग्राफिक सुरक्षा को लागू करने वाले किसी भी व्यक्ति के लिए भी बेहद मूल्यवान है।

स्ट्रिंग को एन्कोड करने के लिए, यदि आपको स्ट्रिंग को ASCII टेक्स्ट में परिवर्तित करना होगा बेस 64 किसी भी तरह से अच्छा है, लेकिन मैं सुझाव दूंगा कि आप इस अतिरिक्त चरण को छोड़ने के लिए HTTP PUT या POST के उपयोग की जांच करें।

4

प्रदान की ग # स्रोत कोड नमूने में, इस लाइन देखना:

Encoding.ASCII.GetString(newClearData); 

UTF-8 Android के लिए डिफ़ॉल्ट एन्कोडिंग, तो एन्क्रिप्टेड स्ट्रिंग (विशेष रूप से इस तरह के चीनी के रूप में गैर- ASCII वर्ण) है पारित हो जाएगा सी # को यूटीएफ -8 मानते हुए। एएससीआईआई एन्कोडिंग का उपयोग कर स्ट्रिंग करने के लिए डीकोड किए गए पाठ को स्कैम्बल किया जाता है। यहां एक बेहतर है,

Encoding.UTF8.GetString(newClearData); 

धन्यवाद!

1

इंटरनेट पर अधिकांश उदाहरण एईएस के कमजोर कार्यान्वयन हैं। कार्यान्वयन के लिए मजबूत होने के लिए, यादृच्छिक चतुर्थ हर समय इस्तेमाल किया जाना चाहिए और कुंजी को धोया जाना चाहिए।

अधिक सुरक्षित (यादृच्छिक चतुर्थ + टुकड़ों में बांटा कुंजी) क्रॉस प्लेटफॉर्म (Android, iOS, सी #) एईएस के कार्यान्वयन के लिए मेरा उत्तर यहाँ देख - https://stackoverflow.com/a/24561148/2480840

संबंधित मुद्दे