2012-04-10 2 views
3

Rijndael을 사용하여 암호화 된 mp4가 있고 다음과 같은 방법으로 C#에서 해독합니다.C# 용 Java의 암호화/암호 해독 도구

System.Security.Cryptography.Rijndael crypt = System.Security.Cryptography.Rijndael.Create(); 

crypt.Key = convertedSecureString; 

byte[] initializationVectorLength = new byte[sizeof(int)]; 
CryptoStream cryptostream = new CryptoStream(inputStream, crypt.CreateDecryptor(), CryptoStreamMode.Read); 
byte[] buffer = new byte[1024]; 
int len; 
while ((len = cryptostream.Read(buffer, 0, buffer.Length)) > 0) 
{ 
    outputStream.Write(buffer, 0, len); 
    buffer = new byte[1024]; 
} 

outputStream.Flush(); 
cryptostream.Close(); 
inputStream.Close(); 

이제이 코드를 Java/Android와 동일한 것으로 변환해야합니다. 솔직하게 어디에서 시작해야할지 모르겠습니다. 나는 많은 옵션으로 혼란스러워합니다. Bouncy Castle을 사용한다고 말하는 사람들도 있고, Apache Commons가 말하는 일부 Java 원시 라이브러리가 있다고하는 사람들도 있습니다. 어떻게해야합니까? CryptoStream 등은 어떻게해야합니까?

나는 키가 안전 키

byte[] convertedSecureString = new byte[this.key.Length]; 
IntPtr ptr = System.Runtime.InteropServices.Marshal.SecureStringToBSTR(this.key); 

for (int i = 0, j = 0; i < this.key.Length * UnicodeByteLength; i = i + UnicodeByteLength, j++) 
{ 
    convertedSecureString[j] = System.Runtime.InteropServices.Marshal.ReadByte(ptr, i); 
} 

try 
{ 
    crypt.Key = convertedSecureString; 
} 

를 할당하는 C#의 코드를 다음 사용하고

UPDATE. 나는 Java에서 동등한 안전하지 않은 키를 가지고있다. 내가 어떻게 자바

UPDATE

Rfc2898DeriveBytes newKey = new Rfc2898DeriveBytes(crypt.Key.ToString(), crypt.IV); 
       Array.Copy(newKey.GetBytes((int)crypt.KeySize/8), crypt.Key, (int)crypt.KeySize/8); 
       Array.Copy(newKey.GetBytes((int)crypt.BlockSize/8), crypt.IV, (int)crypt.BlockSize/8); 

에이 코드 조각을 변환합니까 나는 RFC 2898를 사용하여 키를 국방부와 바이트를 유도하기 위해 C#으로이를 사용하고 - 나는 자바에서 동등한를 찾을 수 없습니다 - 두 번째 주석에서 여기 Java equivalent of C#'s Rfc2898DerivedBytes을 발견했습니다. 그러나 iterator와 dklen에 어떤 값을 부여합니까?

답변

6

Cipher 개체가 필요합니다. 여기에 byte[] aesKeybyte[] iv (초기화 벡터, AES의 경우 항상 16 바이트 여야 함)을 사용하여 가져 오는 방법 중 하나가 있습니다.

// aesKey is 128, 196 or 256-bit key (8, 12 or 16 byte array) 
SecretKeySpec key = new SecretKeySpec(aesKey, "AES"); 

// initialization vector 
IvParameterSpec ivSpec = new IvParameterSpec(iv); 

// create and initialize cipher object 
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING"); 
cipher.init(Cipher.DECRYPT_MODE, key, ivSpec); 

는 해독 모드에서 Cipher 개체가되면 update 방법을 사용하여 암호화 된 데이터를 공급 할 수 있으며, 그것은 당신에게 일반 텍스트 데이터를 반환합니다. 완료되면 doFinal 방법 중 하나를 호출하여 최종 블록을 가져와야합니다.

또는 Cipher 개체와 암호화 된 데이터를 제공하는 원본 입력 스트림을 사용하여 CipherInputStream을 만들 수 있습니다. CipherInputStream에서 데이터를 읽은 다음 원래 입력 스트림에서 데이터를 읽고 해독 한 다음 일반 텍스트 데이터를 반환합니다.

암호화의 경우 Cipher.ENCRYPT_MODECipher.init 방법으로 전달하고 CipherOutputStream을 대신 사용해야합니다.

업데이트 : 전체 예를 들어, 원래 C# 코드에 더 많거나 적은 동등한 기본적으로

// Algorithm, mode and padding must match encryption. 
// Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING"); 

// If you have Bouncycastle library installed, you can use 
// Rijndael/CBC/PKCS7PADDING directly. 
Cipher cipher = Cipher.getInstance("Rijndael/CBC/PKCS7PADDING"); 

// convertedSecureString and initVector must be byte[] with correct length 
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(convertedSecureString, "AES"), 
    new IvParameterSpec(initVector)); 

CipherInputStream cryptoStream = new CipherInputStream(inputStream, cipher); 
byte[] buffer = new byte[1024]; 
int len = cryptoStream.read(buffer, 0, buffer.length); 
while (len > 0) { 
    outputStream.write(buffer, 0, len); 
    len = cryptoStream.read(buffer, 0, buffer.length); 
} 

outputStream.flush(); 
cryptoStream.close(); 
// no need to close inputStream here, as cryptoStream will close it 

는, 자바 Rijndael을 알고리즘을 지원하지 않습니다 (AES는 또는 다른 대답을 참조하십시오 작동하지 않을 수 있습니다) 및 PKCS7 패딩. Bouncycastle 확장 프로그램을 설치 한 다음 Cipher.getInstance("Rijndael/CBC/PKCS7PADDING");을 사용해야합니다. 왜 CBC와 PKCS7 패딩인가? 그것들은 System.Security.Cryptography.Rijndael 클래스의 기본값 인 것 같습니다. 내가 잘못한 경우 올바른 모드와 패딩을 상황에 맞게 사용하십시오.

+0

고마워요! 그러나 계속 진행하는 방법을 아직 확신 할 수 없습니다. C# 코드에서 수행중인 작업과 동일한 수준의 위 설명에 나를 표시하고 있습니다.암호화 된 데이터 파일을 스트림으로 변환하고, 비트를 해독하고 다시 파일에 쓰는 방법을 모르겠습니다. – Slartibartfast

+0

@Vrashabh : 자바에서 동등한 코드로 답변을 업데이트했습니다. –

+0

도움 주셔서 감사합니다! 그것을 시도하고 조금 더 조사하고 다시 질문을하거나 올바른 대답으로 표시 할 수 있습니다. – Slartibartfast

1

C#의 구현에 대해 걱정하지 마십시오. Java 언어에 대한 암호화/암호 해독에 대한 아래 링크를 살펴보십시오. RjIndeal Implementation in Java