2015-09-01 4 views
5

में .net और डिक्रिप्ट में फ़ाइल को एन्क्रिप्ट कैसे करें मैं प्रोजेक्ट पर काम कर रहा हूं जहां हमें एंड्रॉइड एसडी कार्ड में सुरक्षित रूप से पीडीएफ रखना है। हम चाहते हैं कि यह .NET में एन्क्रिप्ट किया जाए क्योंकि इसे एपीआई के माध्यम से स्थानांतरित किया जाना है। मैंने .NET में कार्यान्वित किया है लेकिन एंड्रॉइड में डिक्रिप्ट करने में असमर्थ है।एंड्रॉइड

कोड फ़ाइल को डिक्रिप्ट करने

public static void EncryptFile(string inputFile, string outputFile) 
    { 
     try 
     { 
      string password = @"myKey123"; // Your Key Here 
      UnicodeEncoding UE = new UnicodeEncoding(); 
      byte[] key = UE.GetBytes(password); 

      string cryptFile = outputFile; 
      FileStream fsCrypt = new FileStream(cryptFile, FileMode.Create); 

      RijndaelManaged RMCrypto = new RijndaelManaged(); 
      RMCrypto.Mode = CipherMode.CBC; //remember this parameter 
      RMCrypto.Padding = PaddingMode.PKCS7; //remember this parameter 
      RMCrypto.KeySize = 0x80; 
      RMCrypto.BlockSize = 0x80; 
      CryptoStream cs = new CryptoStream(fsCrypt, 
       RMCrypto.CreateEncryptor(key, key), 
       CryptoStreamMode.Write); 

      FileStream fsIn = new FileStream(inputFile, FileMode.Open); 

      int data; 
      while ((data = fsIn.ReadByte()) != -1) 
      { 
       cs.WriteByte((byte)data); 
      } 

      fsIn.Close(); 
      cs.Close(); 
      fsCrypt.Close(); 

     } 
     catch 
     { 
      Console.WriteLine("Encryption failed!", "Error"); 
     } 
    } 

कोड एक फ़ाइल एन्क्रिप्ट करने के लिए

public static void DecryptFile(string inputFile, string outputFile) 
    { 

     { 
      string password = @"myKey123"; // Your Key Here 

      UnicodeEncoding UE = new UnicodeEncoding(); 
      byte[] key = UE.GetBytes(password); 



      FileStream fsCrypt = new FileStream(inputFile, FileMode.Open); 

      RijndaelManaged RMCrypto = new RijndaelManaged(); 
      RMCrypto.Mode = CipherMode.CBC; //remember this parameter 
      RMCrypto.Padding = PaddingMode.PKCS7; //remember this parameter 
      RMCrypto.KeySize = 0x80; 
      RMCrypto.BlockSize = 0x80; 
      CryptoStream cs = new CryptoStream(fsCrypt, 
       RMCrypto.CreateDecryptor(key, key), 
       CryptoStreamMode.Read); 

      FileStream fsOut = new FileStream(outputFile, FileMode.Create); 

      int data; 
      while ((data = cs.ReadByte()) != -1) 
       fsOut.WriteByte((byte)data); 

      fsOut.Close(); 
      cs.Close(); 
      fsCrypt.Close(); 

     } 
    } 

मैं कोड

public static byte[] decodeFile(String key, byte[] fileData) throws Exception 
{ 
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); //this parameters should not be changed 
    byte[] keyBytes = new byte[16]; 
    byte[] b = key.getBytes("UTF-16"); 
    System.out.println("RAM"+b); 
    int len = b.length; 
    if (len > keyBytes.length) 
     len = keyBytes.length; 
    System.arraycopy(b, 0, keyBytes, 0, len); 
    SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES"); 
    IvParameterSpec ivSpec = new IvParameterSpec(keyBytes); 
    cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec); 
    byte[] decrypted = cipher.doFinal(fileData); 
    return decrypted; 
} 

नीचे का उपयोग कर इस कोड चलाने जब मैं त्रुटि मिलती है एंड्रॉयड में करने की कोशिश की:

error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt 
+1

दो चीजें जो बाहर निकलती हैं: 1) मनमाने ढंग से कुंजी सरणी को छोटा नहीं करना चाहिए; 2) पीकेसीएस 7 एंड्रॉइड कोड में .NET कोड, और पीकेसीएस 5 में पैडिंग योजना का उपयोग किया जा रहा है। – dbugger

+0

मैंने पैडिंग भी देखी। पीकेसीएस 5 पीकेसीएस 7 का सबसेट है इसलिए कोई गारंटी नहीं है कि आपका डिक्रिप्शन कोड इसे समझने में सक्षम होगा (वास्तव में कुछ समय काम कर सकता है लेकिन इसे एक झलक माना जा सकता है)। –

+0

इस समस्या को हल करने के लिए क्या किया जा सकता है। कोई भी कोड या लाइब्रेरी जो – user3036123

उत्तर

3

तो मुझे आपके कोड और आर्किटेक्चर के साथ समस्या का सामना करना पड़ रहा है। जब आप differents भाषा कार्यक्रमों में और विभिन्न envrioment (एंड्रॉइड ("यूनिक्स") और विंडोज़ में क्रिप्टोग्राफी फ़ाइलों का चयन करते हैं तो आपको छोटे और बड़े एंडियन की अवधारणा को याद रखने की आवश्यकता होती है। - the wikipedia Endianness

जावा में स्पष्ट रूप से यह हमेशा डिजिटल एंडियन के साथ खतरा है, इसलिए सबसे महत्वपूर्ण बाइट (एमएसबी) यह कम महत्वपूर्ण बाइट (एलएसबी) का उपयोग करके सी # से अलग है, इस चरण को समस्या का पता लगाने में कठिनाई होती है।

मैंने आपके आधार पर एक कोड बनाया है लेकिन जावा का उपयोग नहीं किया है और एंड्रॉइड नहीं है और कोड काम नहीं कर सका क्योंकि मुझे हमेशा एक ही त्रुटि संदेश BadPaddingException: Given final block not properly padded था। त्रुटि संदेश ने वास्तविक समस्या के बारे में बहुत कुछ नहीं कहा जो key फ़ाइल थी।
जब आप जावा में पढ़ते हैं तो यह .NET से अलग होता है क्योंकि जब आप अपनी कुंजी को एमएसबी के साथ जावा आर्किटेक्चर खतरों को बाइट करते हैं तो आपकी असली कुंजी यह एलएसबी का उपयोग कर रही है। आपके सिस्टम के साथ

//the bKey it's the array of bytes and the key it's the String your are using. 
byte[] bKey = key.getBytes("UTF-16LE"); 



I found the issue with the LE because i read the array of bytes from .NET and from Java and they are different so this gave me the start to find this issue

गुड लक:

तो असली जवाब यह इस you need to convert your key to array of bytes telling to use the Least significative byte so you always have the same array of bytes in .NET and in Java
कुछ इस तरह है!।

Ps .: मुझे डिकोडिंग में कोई समस्या थी क्योंकि बाइट्स की सरणी को डीकोड और डीकोड करते समय आपके पास समस्या थी। मुझे एक पथ मिला है कि आपको जावा में स्ट्रिंग को डीकोड करने के लिए अपाचे कॉमन्स बेस 64 का उपयोग करना चाहिए।
संदर्भ

-बिग/लिटिल endian - Difference between Big Endian and little Endian Byte order
गद्देदार साथ -त्रुटि - Given final block not properly padded
-Decode Base64 - - Decoding a Base64 string in Java


BadPaddingException: Given final block not properly padded
-इस समस्या टिप कुंजी में है

कोड जो मैं परीक्षण करता था।

import java.io.ByteArrayInputStream; 
    import java.io.ByteArrayOutputStream; 
    import java.io.File; 
    import java.io.FileInputStream; 
    import java.io.IOException; 
    import java.nio.ByteBuffer; 
    import java.nio.ByteOrder; 
    import java.nio.charset.Charset; 
    import java.nio.file.Files; 
    import java.nio.file.Path; 
    import java.nio.file.Paths; 
    import javax.crypto.Cipher; 
    import javax.crypto.spec.IvParameterSpec; 
    import javax.crypto.spec.SecretKeySpec; 

    public class HelloWorld { 

     public static void main(String[] args) throws Exception { 
      // TODO Auto-generated method stub 
      Path p = Paths 
        .get("C:\\Users\\casilva\\workspace\\StackOverflow\\src\\tst.enc"); 

      byte[] a = Files.readAllBytes(p); 
      byte[] result = decodeFile("myKey123", a); 
      System.out.println("Result=" + new String(result, "UTF-8")); 
     } 


     public static byte[] decodeFile(String key, byte[] fileData) 
       throws Exception { 
      Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
      byte[] bKey = key.getBytes("UTF-16LE"); 

      SecretKeySpec keySpec = new SecretKeySpec(bKey, "AES"); 

      IvParameterSpec ivSpec = new IvParameterSpec(bKey); 

      cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec); 

      byte[] decrypted = cipher.doFinal(fileData); 

      return decrypted; 
     } 

    }