web developer๐Ÿ‘ฉ๐Ÿป‍๐Ÿ’ป

๋กœ๊ทธ์ธ ์–‘๋ฐฉํ–ฅ ์•”ํ˜ธํ™”(RSA) ๋‹จ๋ฐฉํ–ฅ ์•”ํ˜ธํ™”(SHA 256) ์‚ฌ์šฉํ•˜๊ธฐ ๋ณธ๋ฌธ

Spring

๋กœ๊ทธ์ธ ์–‘๋ฐฉํ–ฅ ์•”ํ˜ธํ™”(RSA) ๋‹จ๋ฐฉํ–ฅ ์•”ํ˜ธํ™”(SHA 256) ์‚ฌ์šฉํ•˜๊ธฐ

natrue 2021. 9. 3. 17:55
728x90

์–‘๋ฐฉํ–ฅ ์•”ํ˜ธํ™”(RSA) ๋‹จ๋ฐฉํ–ฅ ์•”ํ˜ธํ™”(SHA 256) ์ฐจ์ด 

RSA SHA 256
์–‘๋ฐฉํ–ฅ ์•”ํ˜ธํ™” = ๋ณตํ˜ธํ™”๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.  ๋‹จ๋ฐฉํ–ฅ ์•”ํ˜ธํ™” = ๋ณตํ˜ธํ™”๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.
์‚ฌ์šฉ์ž๋Š” ๊ณต๊ฐœ๋œ ํ‚ค์™€ ์ž์‹ ๋งŒ ์•„๋Š” ๊ฐœ์ธํ‚ค๋ฅผ ๊ฐ€์ง„๋‹ค. hash ํ•จ์ˆ˜์˜ ์ผ์ข…
๊ณต๊ฐœํ‚ค, ๊ฐœ์ธํ‚ค๋กœ ์•”ํ˜ธํ™”/๋ณตํ˜ธํ™”๋ฅผ ํ•˜๋Š” ์‹œ์Šคํ…œ SHA ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ํ•œ ์ข…๋ฅ˜๋กœ 256๋น„ํŠธ๋กœ ๊ตฌ์„ฑ
64์ž๋ฆฌ ๋ฌธ์ž์—ด์„ ๋ฐ˜ํ™˜
ํ‚ค์ƒ์„ฑ - ํ‚ค๋ถ„๋ฐฐ - ์•”ํ˜ธํ™” - ๋ณตํ˜ธํ™” ์ˆœ์œผ๋กœ ์ด๋ฃจ์–ด์ง. ๋ณตํ˜ธํ™”๋ฅผ ํ•˜์ง€ ์•Š์•„๋„ ๋˜ ์†๋„๊ฐ€ ๋น ๋ฅด๋‹ค.

web(JSP) -> server(controller)๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋ณด๋‚ผ ๋•Œ ์ค‘๊ฐ„์—์„œ ์ •๋ณด๋ฅผ ๊ฐ€๋กœ์ฑŒ ์ˆ˜ ์žˆ๋‹ค. 

์ด๋Ÿฌํ•œ ๋ณด์•ˆ ๋ฌธ์ œ๋ฅผ ๋ง‰๊ธฐ ์œ„ํ•ด JSP์—์„œ RSA๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์•”ํ˜ธํ™”ํ•ด์ค€๋‹ค..

RSA๋กœ ์•”ํ˜ธํ™”๋œ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ controller์—์„œ ๋ณตํ˜ธํ™”์‹œํ‚ค๊ณ , 

๋ณตํ˜ธํ™”์‹œํ‚จ ํŒŒ๋ผ๋ฏธํ„ฐ ๊ฐ’์„ ๋‹จ๋ฐฉํ–ฅ ์•”ํ˜ธํ™”์ธ SHA256์œผ๋กœ ์•”ํ˜ธํ™”์‹œํ‚จ๋‹ค.

 

RSA ์•”ํ˜ธํ™” 

Rsa.java 

package egovframework.let.utl.sim.service;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.RSAPublicKeySpec;
import javax.crypto.Cipher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

public class Rsa {
	
    public static String RSA_WEB_KEY = "_RSA_WEB_Key_"; // ๊ฐœ์ธํ‚ค session key
    public static String RSA_INSTANCE = "RSA"; // rsa transformation

    /**
     * ๋ณตํ˜ธํ™”
     * 
     * @param privateKey
     * @param securedValue
     * @return
     * @throws Exception
     */
    public String decryptRsa(PrivateKey privateKey, String securedValue) throws Exception {
        Cipher cipher = Cipher.getInstance(Rsa.RSA_INSTANCE);
        byte[] encryptedBytes = hexToByteArray(securedValue);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
        String decryptedValue = new String(decryptedBytes, "utf-8"); // ๋ฌธ์ž ์ธ์ฝ”๋”ฉ ์ฃผ์˜.
        return decryptedValue;
    }
 
    /**
     * 16์ง„ ๋ฌธ์ž์—ด์„ byte ๋ฐฐ์—ด๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.
     * 
     * @param hex
     * @return
     */
    public static byte[] hexToByteArray(String hex) {
        if (hex == null || hex.length() % 2 != 0) { return new byte[] {}; }
 
        byte[] bytes = new byte[hex.length() / 2];
        for (int i = 0; i < hex.length(); i += 2) {
            byte value = (byte) Integer.parseInt(hex.substring(i, i + 2), 16);
            bytes[(int) Math.floor(i / 2)] = value;
        }
        return bytes;
    }
 
    /**
     * rsa ๊ณต๊ฐœํ‚ค, ๊ฐœ์ธํ‚ค ์ƒ์„ฑ
     * 
     * @param request
     */
    public void initRsa(HttpServletRequest request) {
        HttpSession session = request.getSession();
 
        KeyPairGenerator generator;
        try {
            generator = KeyPairGenerator.getInstance(Rsa.RSA_INSTANCE);
            generator.initialize(1024);
 
            KeyPair keyPair = generator.genKeyPair();
            KeyFactory keyFactory = KeyFactory.getInstance(Rsa.RSA_INSTANCE);
            PublicKey publicKey = keyPair.getPublic();
            PrivateKey privateKey = keyPair.getPrivate();
 
            session.setAttribute(Rsa.RSA_WEB_KEY, privateKey); // session์— RSA ๊ฐœ์ธํ‚ค๋ฅผ ์„ธ์…˜์— ์ €์žฅ
 
            RSAPublicKeySpec publicSpec = (RSAPublicKeySpec) keyFactory.getKeySpec(publicKey, RSAPublicKeySpec.class);
            String publicKeyModulus = publicSpec.getModulus().toString(16);
            String publicKeyExponent = publicSpec.getPublicExponent().toString(16);
 
            request.setAttribute("RSAModulus", publicKeyModulus); // rsa modulus ๋ฅผ request ์— ์ถ”๊ฐ€
            request.setAttribute("RSAExponent", publicKeyExponent); // rsa exponent ๋ฅผ request ์— ์ถ”๊ฐ€
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

login.jsp 

RSA ์–‘๋ฐฉํ–ฅ ์•”ํ˜ธํ™”๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„  RSA ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ถ”๊ฐ€๊ฐ€ ํ•„์š”ํ•˜๋‹ค. 

์—ฌ๊ธฐ์„œ js๋ฅผ ๋‹ค์šด๋กœ๋“œ ๋ฐ›์•„ ํ”„๋กœ์ ํŠธ์— ๋„ฃ๋Š”๊ฑธ ์ถ”์ฒœ.

 

JSEncrypt

Introduction When browsing the internet looking for a good solution to RSA Javascript encryption, there is a whole slew of libraries that basically take the fantastic work done by Tom Wu @ http://www-cs-students.stanford.edu/~tjw/jsbn/ and then modify that

travistidwell.com

<script type="text/javascript" src="http://www-cs-students.stanford.edu/~tjw/jsbn/rsa.js"></script>
<script type="text/javascript" src="http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn.js"></script>
<script type="text/javascript" src="http://www-cs-students.stanford.edu/~tjw/jsbn/prng4.js"></script>
<script type="text/javascript" src="http://www-cs-students.stanford.edu/~tjw/jsbn/rng.js"></script>
// ๋น„๋ฐ€๋ฒˆํ˜ธ ์•”ํ˜ธํ™”
function frm_check(){
 var pw = document.loginForm.password.value;
 // rsa ์•”ํ˜ธํ™”
 var rsa = new RSAKey();
 rsa.setPublic($('#RSAModulus').val(),$('#RSAExponent').val());
 $("#password").val(rsa.encrypt(pw));
}

์„œ๋ฒ„ ์ธก์—์„œ RSA ๊ณต๊ฐœํ‚ค์™€ ๊ฐœ์ธํ‚ค(์•”ํ˜ธํ‚ค)๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๊ฐœ์ธํ‚ค๋Š” ์„ธ์…˜์— ์ €์žฅํ•˜๊ณ  ๊ณต๊ฐœํ‚ค๋Š” HTML ๋กœ๊ทธ์ธ ํผ ํŽ˜์ด์ง€์— Input [type=hidden] value ๊ฐ’์— ์„ธํŒ….

<form:form id="loginForm" name="loginForm" action="${pageContext.request.contextPath}/actionLogin.do" method="post" onsubmit="return frm_check();" >
   <div class="user_login_ultop">
    <input type="hidden" id="RSAModulus" value="${RSAModulus}"/>
    <input type="hidden" id="RSAExponent" value="${RSAExponent}"/>
    <ul>
      <li>
          <label for="id"></label>
          <input type="text" class="input_style" title="์•„์ด๋””๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š”." id="id" name="id" maxlength="10"/>
      </li>
      <li>
          <label for="password"></label>
          <input type="password" class="input_style" maxlength="25" title="๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š”." id="password" name="password"/>
      </li>
      <li>
          <input type="checkbox" name="checkId" id="checkId" /><label for="checkId">ID์ €์žฅ</label>
      </li>
    </ul>
  	<input type="submit" alt="๋กœ๊ทธ์ธ ํ•˜๊ธฐ" value="๋กœ๊ทธ์ธ" class="btn_style"/>
   </div>
</form:form>

RSA ๋ณตํ˜ธํ™” 

LoginController.java 

Rsa r = new Rsa();
HttpSession session = request.getSession();
//๋กœ๊ทธ์ธ์ „์— ์„ธ์…˜์— ์ €์žฅ๋œ ๊ฐœ์ธํ‚ค๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค.
PrivateKey privateKey = (PrivateKey) session.getAttribute(Rsa.RSA_WEB_KEY);
//์•”ํ˜ธํ™” ๋œ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๋ณตํ˜ธํ™” ์‹œํ‚จ๋‹ค.
String password = r.decryptRsa(privateKey, LoginVO.getPassword());
// ShA 256 ์•”ํ˜ธํ™” = ๋‹จ๋ฐฉํ–ฅ 
String sha = EgovFileScrty.encryptPassword(password);
LoginVO.setPassword(sha);

SHA 256 ์•”ํ˜ธํ™” 

EgovFileScrty.java 

/**
* ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์•”ํ˜ธํ™”ํ•˜๋Š” ๊ธฐ๋Šฅ(๋ณตํ˜ธํ™”๊ฐ€ ๋˜๋ฉด ์•ˆ๋˜๋ฏ€๋กœ SHA-256 ์ธ์ฝ”๋”ฉ ๋ฐฉ์‹ ์ ์šฉ).
* 
* deprecated : ๋ณด์•ˆ ๊ฐ•ํ™”๋ฅผ ์œ„ํ•˜์—ฌ salt๋กœ ID๋ฅผ ์ง€์ •ํ•˜๋Š” encryptPassword(password, id) ์‚ฌ์šฉ
*
* @param String data ์•”ํ˜ธํ™”ํ•  ๋น„๋ฐ€๋ฒˆํ˜ธ
* @return String result ์•”ํ˜ธํ™”๋œ ๋น„๋ฐ€๋ฒˆํ˜ธ
* @exception Exception
*/
@Deprecated
public static String encryptPassword(String data) throws Exception {

  if (data == null) {
  return "";
  }

  byte[] plainText = null; // ํ‰๋ฌธ
  byte[] hashValue = null; // ํ•ด์‰ฌ๊ฐ’
  plainText = data.getBytes();

  MessageDigest md = MessageDigest.getInstance("SHA-256");

  hashValue = md.digest(plainText);

 return new String(Base64.encodeBase64(hashValue));
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

์ฐธ๊ณ  : 

 

GitHub - kenu/egov

Contribute to kenu/egov development by creating an account on GitHub.

github.com

 

RSA (๋น„๋Œ€์นญ ์•”ํ˜ธํ™” ์•Œ๊ณ ๋ฆฌ์ฆ˜)

์‚ฌ์šฉํ•˜๋Š” ๋ชฉ์ WEB ์„œ๋ฒ„์— SSL ์„ค์น˜ ์—†์ด ๋กœ๊ทธ์ธ์ฒ˜๋ฆฌํ• ๋•Œ ํ‰๋ฌธ์œผ๋กœ ์ „์†กํ• ๊ฒฝ์šฐ ์ค‘๊ฐ„์—์„œ ์ •๋ณด๋ฅผ ๊ฐ€๋กœ์ฑ„์–ด ๊ฐ€๋กœ์ฑˆ ๊ณ„์ •์ •๋ณด๋ฅผ ๊ถŒํ•œ์ด ์—†๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์‹œ์Šคํ…œ์— ๋กœ๊ทธ์ธ ํ•œํ›„ ์‹œ์Šคํ…œ์„ ์†์ƒ์‹œํ‚ฌ์ˆ˜๋„

velog.io