너무어려웡
502
2017-06-14 14:40:57
5
1222

spring 이용해서 웹 게시판 만들고 있는 중인데요


공부 겸 spring 이용해서 게시판 만들어 보는 중인데요.

로그인 구현 하는걸 살펴보다가, rsa에 관해서 알게 되어서 구현해 볼까 하는데요.

게시글들을 쭉 읽어 보다

"그런데 문제는 실제 필드에서는 이렇게 사용하지 않죠. 이유는 서버와 클라이언트간에 통신을 하는데 위의 소스는 그냥 로컬에서 스스로 인코딩하고 디코딩하는 로직입니다.  당연히 서버와 클라이언트간에 키공유 이슈는 빠져있습니다."

라는 구문을 봤는데... 이 부분이 정확히 이해가 안 되는데 무슨 말일까요..?


0
0
  • 답변 5

  • Taewoong La
    518
    2017-06-14 14:44:01

    인용하신 글로만 봐서는, "위의 소스"라고 지칭된 로직 자체가 스스로 인코딩/디코딩 하는 로직이니, 실제 서버-클라 관계에서 그대로 가져다 쓸 로직이 아니다.

    라는 글 내용 그대로의 뜻으로만 이해되네요 ㅎㅎ

    0
  • 너무어려웡
    502
    2017-06-14 14:48:25


    import java.security.Key;  
    import java.security.KeyFactory;  
    import java.security.KeyPair;  
    import java.security.KeyPairGenerator;  
    import java.security.spec.RSAPrivateKeySpec;  
    import java.security.spec.RSAPublicKeySpec;  
    import javax.crypto.Cipher;  
    public class TestRsa  
    {
     public static void main( String [] args )
     {
      try
      {
       // RSA 공개키/개인키를 생성한다.
       KeyPairGenerator clsKeyPairGenerator = KeyPairGenerator.getInstance("RSA");
       clsKeyPairGenerator.initialize(2048);
    
       KeyPair clsKeyPair = clsKeyPairGenerator.genKeyPair();
       Key clsPublicKey = clsKeyPair.getPublic();
       Key clsPrivateKey = clsKeyPair.getPrivate();
       KeyFactory fact = KeyFactory.getInstance("RSA");
       RSAPublicKeySpec clsPublicKeySpec = fact.getKeySpec( clsPublicKey, RSAPublicKeySpec.class);
       RSAPrivateKeySpec clsPrivateKeySpec = fact.getKeySpec( clsPrivateKey, RSAPrivateKeySpec.class);
       System.out.println( "public key modulus(" + clsPublicKeySpec.getModulus( ) + ") exponent(" + clsPublicKeySpec.getPublicExponent( ) + ")" );
       System.out.println( "private key modulus(" + clsPrivateKeySpec.getModulus( ) + ") exponent(" + clsPrivateKeySpec.getPrivateExponent( ) + ")" );
    
       // 암호화 한다.
       String strPinNumber = "1234567890";
    
       Cipher clsCipher = Cipher.getInstance("RSA");
       clsCipher.init( Cipher.ENCRYPT_MODE, clsPublicKey );
        byte[] arrCipherData = clsCipher.doFinal( strPinNumber.getBytes( ) );
        String strCipher = new String( arrCipherData );
        System.out.println( "cipher(" + strCipher + ")" );
    
        // 복호화 한다.
        clsCipher.init( Cipher.DECRYPT_MODE, clsPrivateKey );
        byte[] arrData = clsCipher.doFinal( arrCipherData );
    
        String strResult = new String( arrData );
        System.out.println( "result(" + strResult + ")" );
      }
      catch( Exception e )
      {
    
      }
     }
    }

    게시 소스가 이건데요

    원래라면 이 소스가 서버 따로 클라이언트 따로 소스가 나뉘어져야 된다는 말인건가요?

    0
  • Taewoong La
    518
    2017-06-14 15:09:10

    "그런데 문제는 실제 필드에서는 이렇게 사용하지 않죠. 이유는 서버와 클라이언트간에 통신을 하는데 위의 소스는 그냥 로컬에서 스스로 인코딩하고 디코딩하는 로직입니다.  당연히 서버와 클라이언트간에 키공유 이슈는 빠져있습니다."


    RSA는 간단하게 설명하자면 데이터를 public key로 암호화하고 private key로 복호화하는 알고리즘입니다. RSA를 로그인처럼 서버-클라 간의 관계에서 쓰기 위해서는 서버쪽에서 public key로 암호화를 하고 클라쪽에서 private key로 복호화를 한다던지 하는 "서버와 클라이언트간에 키공유 이슈"에 대한 고민이 필요하겠죠.


    A 유저가 있다고 해보겠습니다.

    A가 회원가입을 할 때 public key, private key를 생성하고, public key는 서버에 저장하고 private key는 클라에 저장하겠죠. (private key는 개인키 이기 때문에 서버에 저장되지 않고 개인이 보관합니다.)

    로그인을 시도했을 때 성공했다면 뭔가 정보들을 public key로 암호화해서 클라에게 전송할겁니다. 이를 클라가 private key로 복호화해서 쓰는거죠.


    이때, 만약 클라가 private key를 잃어버린다면? 모바일의 경우 기기를 바꾼다면? key를 다시 발급받아야하겠죠. 이런 키공유 이슈에 대한 이야기를 한게 아닐까 싶네요.

    1
  • Taewoong La
    518
    2017-06-14 15:12:37

    혹은 public key로 암호화된 정보를 서버에서 저장하고 있고, 클라에서 private key를 보내서 복호화가 되면 로그인이 된다던지, 정보를 가져온다던지... 등등 방법은 다양합니다.


    결론은 위의 소스는 암/복호화가 한 곳에서 이뤄지기 때문에 그 자체만으로는 아무런 효용성이 없다는 당연한 이야기를 하신 것 같습니다.

    0
  • 너무어려웡
    502
    2017-06-15 04:07:15

    아하 그렇군요 ㅠㅠ

    이해 됐습니다! 감사합니다!

    1
  • 로그인을 하시면 답변을 등록할 수 있습니다.