2014-07-19 3 views
0

일부 암호화를 구현해야하는 안드로이드 애플리케이션을 개발 중입니다. 동시에 프로덕션 환경에있는 다른 버전의 응용 프로그램 (예 : WP 플랫폼)과의 호환성을 유지해야합니다. 나는 자바를 구현하기 위해 노력했다자바에서 C# 암호화 구현

static public byte[] Encrypt(String passphrase, byte[] data) 
    { 
     //encrypted data 
     byte[] buffer = null; 

     //crypto handles 
     IntPtr hProvider = IntPtr.Zero; 
     IntPtr hKey = IntPtr.Zero; 

     try 
     { 

      if (!WinApi.CryptAcquireContext(ref hProv, null, WinApi.MS_DEF_PROV, 
       WinApi.PROV_RSA_FULL, WinApi.CRYPT_VERIFYCONTEXT)) 
       Failed("CryptAcquireContext"); 

      //128 bit hash object 
      if (!WinApi.CryptCreateHash(hProv, 
       WinApi.CALG_MD5, IntPtr.Zero, 0, ref hHash)) 
       Failed("CryptCreateHash"); 

    // add passphrase to hash 
      byte[] keyData = ASCIIEncoding.ASCII.GetBytes(passphrase); 
      if (!WinApi.CryptHashData(hHash, keyData, (uint)keyData.Length, 0)) 
       Failed("CryptHashData"); 

      // create 40 bit crypto key from passphrase hash 
      if (!WinApi.CryptDeriveKey(hProv, WinApi.CALG_RC2, 
       hHash, WinApi.CRYPT_EXPORTABLE, ref hKey)) 
       Failed("CryptDeriveKey"); 

      // determine how large of a buffer is required 
      // to hold the encrypted data 
      uint dataLength = (uint)data.Length; 
      uint bufLength = (uint)data.Length; 
      if (!WinApi.CryptEncrypt(hKey, IntPtr.Zero, true, 
       0, null, ref dataLength, bufLength)) 
       Failed("CryptEncrypt"); 

      // allocate and fill buffer with encrypted data 
      buffer = new byte[dataLength]; 
      Buffer.BlockCopy(data, 0, buffer, 0, data.Length); 

      dataLength = (uint)data.Length; 
      bufLength = (uint)buffer.Length; 
      if (!WinApi.CryptEncrypt(hKey, IntPtr.Zero, true, 
       0, buffer, ref dataLength, bufLength)) 
       Failed("CryptEncrypt"); 
     } 
     ....... 
    } 

:

이 C# 코드입니다. AFAIK, 안드로이드에는 기본 RC2 암호 공급자가 없으므로, Spongy Castle 라이브러리 (안드로이드 용 bouncycastle 포크)를 사용했습니다.

이 내 자바 코드 :

public static byte[] encryptLB(byte[] key, byte[] iv, byte[] unencrypted) 
       throws NoSuchAlgorithmException, ... { 
      MessageDigest digest = MessageDigest.getInstance("MD5"); 
      digest.update(key); 
      byte[] hash = digest.digest(); //build the hash (128 bit) 

       Cipher cipher = Cipher.getInstance("RC2/CBC/PKCS5Padding"); 
       cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(hash, "RC2")); 
       byte[] unByte = unencrypted; 
       byte[] encrypted = cipher.doFinal(unencrypted); 
       return encrypted; 
      } 

그리고 이러한 기능의 결과가 다릅니다. 내가 뭘 잘못하고있어?

어떻게 제대로합니까? 모든 예제 및 제안을 환영합니다.

과 관련하여 최선을 다하겠습니다.

UPD 주요 목표는 두 기능에서 동일한 바이트 배열을 얻는 것입니다. 나는 C# 코드를 수정할 수 없다. 우선, 내가 오른쪽 C# 1 -code 함께 오전 명확히 할 :

  • passphrase의 바이트 배열 MD5 해시를 생성
  • 는이 키에 사용되는 고유 WinApi.CryptDeriveKey 기능
  • 를 이용하여 암호화 키를 생성

둘째, 나는 WinApi.CryptDeriveKey의 아날로그가 있는지 여부를 알고 싶습니다. 이것이 주요한 문제입니다.

위의 문제 (CryptDeriveKey)가 유일한 것인지 확실하지 않으므로 죄송합니다. 내 질문이 너무 일반적입니다.

+0

* 암호화 * 또는 * 해싱 *을 수행하려고합니까? 그것들은 매우 다르다. 당신은 Java 코드에서 해싱하는 것처럼 보인다. 명확한 이유없이 Windows API를 사용하고 있기 때문에 C# 코드는 그리 명확하지 않습니다. .NET에 직접 많은 암호화 API가 있습니다. –

+0

난 그냥 자바에서 C#으로 작성된 알고리즘을 구현하는 중이 야. 불행히도, WinApi 및 C#의 모범 사례에 익숙하지 않으며,이 코드는 제 것이 아닙니다. 내가 알기로,이 메소드 (C#)는 'passphrase'에서 MD5 해시를 생성 한 다음 비밀 키로 사용합니다. 그리고이 단계'if (! WinApi.CryptDeriveKey (hProv, WinApi.CALG_RC2, hHash, WinApi.CRYPT_EXPORTABLE, ref hKey))'는 여전히 나에게 불분명하다. MSDN에서는 해시 데이터에서 키를 생성한다고합니다. 이 함수에 대한 자바 또는 오픈 소스 아날로그가 있습니까? –

+1

그럼 실제로 달성하려는 것은 무엇입니까? 다른 것에 앞서 그것에 대해 분명히해야합니다. –

답변

0

불행히도 지금 당장이 기능을 테스트 할 Windows 컴퓨터에 액세스 할 수 없지만 여기에 상호 운용이 가능해야한다고 생각합니다.

public static byte[] encrypt(String passphrase, byte[] data) throws Exception { 

    // Hash the ASCII-encoded passphrase with md5 

    byte[] keyData = passphrase.getBytes(Charset.forName("US-ASCII")); 
    MessageDigest md = MessageDigest.getInstance("MD5"); 
    byte [] md5HashOfKey = md.digest(keyData); 

    // Need to use bouncycastle (spongycastle on Android) to get RC2 

    Security.addProvider(new BouncyCastleProvider()); 

    Cipher rc2 = Cipher.getInstance("RC2/CBC/PKCS5PADDING"); 

    // Create an RC2 40-bit key from the 1st 5 bytes of the hash. 

    SecretKeySpec rc2KeySpec = new SecretKeySpec(md5HashOfKey, 0, 5, "RC2"); 
    rc2.init(Cipher.ENCRYPT_MODE, rc2KeySpec); 

    byte [] cipher = rc2.doFinal(data); 

    return cipher; 
}