본문 바로가기
java

비밀키(개인키)를 이용한 디지털 서명 javascript and java

by 후린트 2023. 2. 9.
반응형

한번에 pkcs8 format privateKey 생성 

$ openssl genrsa 1024 | openssl pkcs8 -topk8 -nocrypt -out dd_private.pem
Generating RSA private key, 1024 bit long modulus
.....................++++++
............................++++++
e is 65537 (0x10001)


-----BEGIN PRIVATE KEY-----
BASE64ENCODED_TEXT....
....
...
...
...
-----END PRIVATE KEY-----

JAVA
참조 : https://juinthyme.tistory.com/59

import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;

public class Signed {

	public static void main(String args[]){
		String message = "abcdefghijklmnop";
		String sigendString = createSignedString(message);
	}


	public static String createSignedString(String msg) {
		try {
			PrivateKey privateKey = getPrivateKeyFromPEM();

			Signature privateSignature = Signature.getInstance("SHA256withRSA");
			privateSignature.initSign(privateKey);
			privateSignature.update(msg.getBytes("utf-8"));

			byte[] signedData = privateSignature.sign();
			String signedString = new String( signedData );


			String signatureString = Base64.getEncoder().encodeToString(signedData);
			return signatureString;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public static PrivateKey getPrivateKeyFromPEM() {
		String privateKeyStr = "PEM파일에서헤더와푸터를제외한BASE64인코딩된내용";
		KeyFactory keyFactory = null;
		try {
			byte[] encoded = Base64.getDecoder().decode(privateKeyStr.getBytes("utf-8"));

			keyFactory = KeyFactory.getInstance("RSA");
			return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encoded));
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}


}

 

Javascript

https://www.npmjs.com/package/node-forge

    <script type="module">
        import forge from 'node-forge';
        import Buffer from 'Buffer';
        window.forge = forge;
        window.buffer = Buffer;
        window.privateKeyStr = "PEM파일에서헤더와푸터를제외한BASE64인코딩된내용";

		

      window.signed = function(msg){
          /* msg messageDigest 처리 */
          const messageDigest = forge.md.sha256.create();
          messageDigest.update(msg, 'utf8');

          /* private pem 으로 privateKey 생성 */
          let privateKey = forge.pki.privateKeyFromPem(getPrivateKeyPem());
          var signedData = privateKey.sign(messageDigest);

          /* 서명된 msg를 base64로 인코딩 처리 */
          var decodeSignedData  =  forge.util.binary.raw.decode(signedData);
          var signedString =  buffer.Buffer.from(decodeSignedData).toString(
            'base64'
          );
          return signedString;
      }

	  window.getPrivateKeyPem = function(){
            var privateKeyPem =  `-----BEGIN PRIVATE KEY-----\n${privateKeyStr
                .replace(/-/g, '+')
                .replace(/_/g, '/')
                .replace(/(\S{64}(?!$))/g, '$1\n')}\n-----END PRIVATE KEY-----\n`;
            return privateKeyPem;
      }
    </script>
    var sigendString = signed('aaaaaaaaaaaaaaaaaaaaaa');

2일간에 삽질로 자바와 javascript sign 처리 

javascript는 전달하는 msg를 MessageDigest 처리가 필요하지만 
java는 signature.update 실행시에 내부에서 MessageDigest 처리가 진행되므로 msg를 Digest 처리할 필요가 없다.

 

반응형

'java' 카테고리의 다른 글

gradlew 프록시 서버 설정  (0) 2024.02.01
springboot Invalid 'expires' attribute  (0) 2023.10.10
gradle project 경로 확인  (0) 2022.11.23
spring redirectUrl 생성  (0) 2022.08.18
gradle dependency 캐시 지우기  (0) 2022.08.02