2017-02-27 7 views
2

그래서 자바에서 RSA를 암호화하고 해독 할 수있는 방법을 찾으려고합니다. 암호화는 javas API로하고 biginteger로 해독합니다. 나는 끝났다. 그러나 biginteger는 나에게 이상한 결과를 때때로 준다. 이 제공Java RSA로 암호화 및 BigInteger로 암호 해독

import java.math.BigInteger; 
import java.security.InvalidKeyException; 
import java.security.KeyPair; 
import java.security.KeyPairGenerator; 
import java.security.NoSuchAlgorithmException; 
import java.security.NoSuchProviderException; 
import java.security.Security; 
import java.security.interfaces.RSAPrivateKey; 
import java.security.interfaces.RSAPublicKey; 
import java.security.spec.InvalidKeySpecException; 

import javax.crypto.BadPaddingException; 
import javax.crypto.Cipher; 
import javax.crypto.IllegalBlockSizeException; 
import javax.crypto.NoSuchPaddingException; 

import org.bouncycastle.jce.provider.BouncyCastleProvider; 

public class cryptoAndBigIntegerFIX { 
    public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidKeySpecException{ 
     Security.addProvider(new BouncyCastleProvider()); 
     System.out.println("input <> encrypted <> decrypted"); 
     cryptoAndBigIntegerFIX.keygen(); 

     BigInteger encryptbytes; 
     BigInteger decryptbytes; 

     //Multiple tests with powers of 3 for some reason :D 
     for(int i=1;i<1000;i*=3){ 
      encryptbytes = cryptoAndBigIntegerFIX.encrypt(new BigInteger(""+i)); 
      System.out.print(i + " <> " + encryptbytes.intValue() + " <> "); 
      decryptbytes = cryptoAndBigIntegerFIX.decrypt(encryptbytes); 
      System.out.println(decryptbytes.intValue());    
     } 
    } 

    public static RSAPrivateKey priv; 
    public static RSAPublicKey pub; 

    public static void keygen() throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException{ 
     KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA"); 

     generator.initialize(512); 
     KeyPair keyPair = generator.generateKeyPair(); 
     priv = (RSAPrivateKey) keyPair.getPrivate(); 
     pub = (RSAPublicKey) keyPair.getPublic();  
    } 

    //Encrypt with javas API 
    public static BigInteger encrypt(BigInteger bg) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchProviderException{ 
     byte[] encoded; 
     Cipher cipher=Cipher.getInstance("RSA/ECB/NoPadding"); 
     cipher.init(Cipher.ENCRYPT_MODE, pub); 
     encoded=cipher.doFinal(bg.toByteArray()); 
     return new BigInteger(encoded); 
    } 

    //Decrypt manually 
    public static BigInteger decrypt(BigInteger bg){ 
     BigInteger decoded = bg.modPow(priv.getPrivateExponent(),priv.getModulus()); 
     return decoded; 

    } 

} 

출력은 다음과 같습니다 : 나는 암호화하고 세 가지의 능력을 해독하려고으로 올바른

input <> encrypted <> decrypted 
1 <> 1 <> 1 
3 <> 1088098617 <> 3 
9 <> 1947497039 <> 9 
27 <> -1665331145 <> 27 
81 <> -1064046970 <> 81 
243 <> -599005266 <> 243 
729 <> -1534949160 <> 729 

이 내 코드입니다. 하지만 때때로 다음과 같은 잘못된 출력을 제공합니다.

input <> encrypted <> decrypted 
1 <> 1 <> 1 
3 <> 1693488667 <> 3 
9 <> -924345856 <> 9 
27 <> 777525903 <> 144224668 
81 <> -1602799071 <> 765474161 
243 <> -227258229 <> 243 
729 <> 1097077312 <> 296615835 

꽤 이상한가요? 내 코드에 어떤 문제가 있습니까? 그것은 biginteger 또는 열쇠를 생성하는 방식으로 문제가 무엇입니까?

+0

왜? 'Cipher'는 암호 해독 모드와 암호화 모드를 제공합니다. – EJP

+0

그것은 강사가 하나의 똑같은 역할을한다는 것을 증명하는 "과제"였습니다. 그는 나에게 JUNIT 테스트도해야한다고 말했습니다. 그는 위의 오류에 대해 아무 말도하지 않았으므로 컴파일 할 때 잘못된 대답이 없기 때문에 아무 것도 알지 못했을 것입니다. 문제는, 가끔 잘못된 대답을 얻을 때 JUNIT 테스트 케이스를 만들지도 않는다는 것입니다. – David

답변

4

정확한 출력 결과 고정 코드에서 두 개의 실수있다 다음 BigInteger 생성자 기대하면서

  • RSA는 부호 (빅 엔디안) 값의 부호화를 나타내는 바이트 배열을 반환 될 a 부호가 (빅 엔디안) 값;
  • 변환 (즉, 대부분의 정보를 잃어 버림) 인 을 사용하여 ~ 512 비트 정수를 32 비트 int으로 변환합니다.

는이 다음 코드를 사용하여 해결하려면 주 :

for (int i = 1; i < 1000; i *= 3) { 
    encryptbytes = encrypt(new BigInteger("" + i)); 
    decryptbytes = decrypt(encryptbytes); 
    System.out.printf("%d <> %d <> %d%n", i, encryptbytes, decryptbytes); // <-- CHANGED 
} 

및 수정이처럼 encrypt 방법 :

public static BigInteger encrypt(BigInteger bg) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchProviderException{ 
    byte[] encoded; 
    Cipher cipher=Cipher.getInstance("RSA/ECB/NoPadding"); 
    cipher.init(Cipher.ENCRYPT_MODE, pub); 
    encoded=cipher.doFinal(bg.toByteArray()); 
    // always return a positive number, all numbers in RSA range from 0 to N, the modulus 
    return new BigInteger(1, encoded); // <-- CHANGED 
} 

출력 :

,536,913을 63,210
1 <> 1 <> 1 
3 <> 5391244976364305547335484748020521942086098609617330384518129302949818422340576199311962549547267600132422679070440104879858341377467952359964277978034437 <> 3 
9 <> 6124821216540311592072512276604516925109106437800474377305024835746311326643844937438898166014089888517013623381274703706957136996030394061334489396421471 <> 9 
27 <> 7417955231776825208837885603385850571492475371613109504900294367112291012186031184819506881671785651668774452694772296927652149185293472327267855826108811 <> 27 
81 <> 4379633872520787556108807271103986910459839084415924804306544674047140392288351081810043910720852387318488882506988222018682090612584816530149697340650488 <> 81 
243 <> 7246933972891920591130671309726014055879369415307203680175037003794552795366338573568427805702031164261947749468386326443821678079330776559688467025349997 <> 243 
729 <> 1545447812776244759821683256943744637177323415383752406121617316817182282617298911713206245407992744746920675542053503316837741108184755354755351275313816 <> 729 

다른 독자에 대한 경고 : 결코 일반 텍스트/원자재 RSA (자바 "RSA/ECB/NoPadding")가 안전하지 사용하지 않습니다. 대신 RSA OAEP가있는 하이브리드 암호화 시스템을 사용해보십시오. 코드를 복사/붙여 넣기하지 마시오.

+0

고마워요! 나는 이것이 그 일과 관련이 있다고 의심했다. 그러나 나는 해결책을 알지 못했다. 그리고 네, 노파 딩은 학교 과제 일뿐입니다. – David