- update jwt
- add security
This commit is contained in:
@@ -11,9 +11,9 @@ plugins {
|
||||
|
||||
dependencies {
|
||||
// https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-api
|
||||
implementation("io.jsonwebtoken:jjwt-api:0.11.2")
|
||||
implementation("io.jsonwebtoken:jjwt-api:0.12.3")
|
||||
|
||||
// https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-impl
|
||||
runtimeOnly("io.jsonwebtoken:jjwt-impl:0.11.2")
|
||||
runtimeOnly("io.jsonwebtoken:jjwt-jackson:0.11.2")
|
||||
runtimeOnly("io.jsonwebtoken:jjwt-impl:0.12.3")
|
||||
runtimeOnly("io.jsonwebtoken:jjwt-jackson:0.12.3")
|
||||
}
|
||||
|
||||
@@ -29,12 +29,20 @@ public class JwtSample {
|
||||
}
|
||||
|
||||
public static String generateToken() throws InvalidKeyException {
|
||||
return Jwts.builder()
|
||||
/*return Jwts.builder()
|
||||
.setHeaderParam(Header.TYPE, Header.JWT_TYPE)
|
||||
.setIssuer("Elex")
|
||||
.setExpiration(Date.from(Instant.now().plus(3, ChronoUnit.HOURS)))
|
||||
.claim("userId", 3)
|
||||
.signWith(Keys.hmacShaKeyFor(key))
|
||||
.compact();*/
|
||||
return Jwts.builder()
|
||||
.header().type(Header.JWT_TYPE)
|
||||
.and()
|
||||
.issuer("Elex")
|
||||
.expiration(Date.from(Instant.now().plus(3, ChronoUnit.HOURS)))
|
||||
.claim("userId", 3)
|
||||
.signWith(Keys.hmacShaKeyFor(key))
|
||||
.compact();
|
||||
}
|
||||
|
||||
@@ -53,11 +61,16 @@ public class JwtSample {
|
||||
throws UnsupportedJwtException, MalformedJwtException, SignatureException, ExpiredJwtException,
|
||||
MissingClaimException, IncorrectClaimException {
|
||||
|
||||
return Jwts.parserBuilder()
|
||||
/*return Jwts.parserBuilder()
|
||||
.setSigningKey(key)
|
||||
.requireIssuer("Elex") // 토큰의 Issuer 일치 여부 확인
|
||||
.build()
|
||||
.parseClaimsJws(parseHeader(token));
|
||||
.parseClaimsJws(parseHeader(token));*/
|
||||
return Jwts.parser()
|
||||
.verifyWith(Keys.hmacShaKeyFor(key))
|
||||
.requireIssuer("Elex") // 토큰의 Issuer 일치 여부 확인
|
||||
.build()
|
||||
.parseSignedClaims(parseHeader(token));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -84,7 +97,7 @@ public class JwtSample {
|
||||
final String authHeader = "Bearer " + token;
|
||||
Jws<Claims> claims = parseToken(authHeader);
|
||||
System.out.println(claims);
|
||||
final int userId = claims.getBody().get("userId", Integer.class);
|
||||
final int userId = claims.getPayload().get("userId", Integer.class);
|
||||
System.out.println("User Id: " + userId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,10 +9,14 @@ package kr.pe.elex.examples;
|
||||
|
||||
import io.jsonwebtoken.Header;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import io.jsonwebtoken.io.CompressionAlgorithm;
|
||||
import io.jsonwebtoken.security.Keys;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.security.Key;
|
||||
import javax.crypto.SecretKey;
|
||||
import java.security.*;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Base64;
|
||||
@@ -24,23 +28,39 @@ import static org.junit.jupiter.api.Assertions.*;
|
||||
class SampleTest {
|
||||
|
||||
@Test
|
||||
void test(){
|
||||
void test() throws NoSuchAlgorithmException, InvalidKeySpecException {
|
||||
byte[] key = new byte[32];
|
||||
new Random().nextBytes(key);
|
||||
final Key signingKey = Keys.hmacShaKeyFor(key);
|
||||
//final SecretKey signingKey = Keys.hmacShaKeyFor(key);
|
||||
KeyPair keyPair = Jwts.SIG.RS384.keyPair().build();
|
||||
PrivateKey privateKey = keyPair.getPrivate();
|
||||
PublicKey publicKey = keyPair.getPublic();
|
||||
String base64PublicKey = Base64.getEncoder().encodeToString(publicKey.getEncoded());
|
||||
|
||||
String jwt = Jwts.builder()
|
||||
.setHeaderParam(Header.TYPE, Header.JWT_TYPE)
|
||||
.setIssuer("Elex")
|
||||
.setExpiration(Date.from(Instant.now().plus(3, ChronoUnit.HOURS)))
|
||||
.header().type("JWT")
|
||||
.and()
|
||||
.issuer("Elex")
|
||||
.expiration(Date.from(Instant.now().plus(3, ChronoUnit.HOURS)))
|
||||
.claim("userId", 3)
|
||||
.signWith(signingKey)
|
||||
.signWith(keyPair.getPrivate())
|
||||
.compact();
|
||||
System.out.println(jwt);
|
||||
String issuer = Jwts.parserBuilder()
|
||||
.setSigningKey(signingKey)
|
||||
//.requireIssuer("Elex") // 토큰의 Issuer 일치 여부 확인
|
||||
|
||||
X509EncodedKeySpec ukeySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(base64PublicKey));
|
||||
PublicKey pKey = KeyFactory.getInstance("RSA").generatePublic(ukeySpec);
|
||||
|
||||
Integer userId = Jwts.parser()
|
||||
.verifyWith(pKey)
|
||||
.requireIssuer("Elex") // 토큰의 Issuer 일치 여부 확인
|
||||
.build()
|
||||
.parseClaimsJws(jwt).getBody().getIssuer();
|
||||
System.out.println(issuer);
|
||||
.parseSignedClaims(jwt).getPayload().get("userId", Integer.class);
|
||||
System.out.println(userId);
|
||||
String alg = Jwts.parser()
|
||||
.verifyWith(pKey)
|
||||
.requireIssuer("Elex") // 토큰의 Issuer 일치 여부 확인
|
||||
.build()
|
||||
.parseSignedClaims(jwt).getHeader().getAlgorithm();
|
||||
System.out.println(alg);
|
||||
}
|
||||
}
|
||||
|
||||
3
security/README.md
Normal file
3
security/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Security
|
||||
|
||||
https://github.com/jwtk/jjwt
|
||||
14
security/build.gradle.kts
Normal file
14
security/build.gradle.kts
Normal file
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Examples for Java
|
||||
*
|
||||
* Copyright (c) 2023. Elex. All Rights Reserved.
|
||||
* https://www.elex-project.com/
|
||||
*/
|
||||
|
||||
plugins {
|
||||
id("elex-java")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
}
|
||||
20
security/logback.xml
Normal file
20
security/logback.xml
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Examples for Java
|
||||
~
|
||||
~ Copyright (c) 2021. Elex. All Rights Reserved.
|
||||
~ https://www.elex-project.com/
|
||||
-->
|
||||
|
||||
<configuration>
|
||||
|
||||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="TRACE">
|
||||
<appender-ref ref="CONSOLE" />
|
||||
</root>
|
||||
</configuration>
|
||||
45
security/src/main/java/kr/pe/elex/examples/AESKeys.java
Normal file
45
security/src/main/java/kr/pe/elex/examples/AESKeys.java
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2024. Elex. All Rights Reesrved.
|
||||
* https://www.elex-project.com/
|
||||
*/
|
||||
|
||||
package kr.pe.elex.examples;
|
||||
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.util.Base64;
|
||||
|
||||
public class AESKeys {
|
||||
public static SecretKey generateSecretKey() throws NoSuchAlgorithmException {
|
||||
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
|
||||
keyGenerator.init(128, new SecureRandom());
|
||||
return keyGenerator.generateKey();
|
||||
}
|
||||
|
||||
public static SecretKey generateSecretKey(char[] password, byte[] salt, int iteration) throws NoSuchAlgorithmException, InvalidKeySpecException {
|
||||
PBEKeySpec keySpec = new PBEKeySpec(password, salt, iteration);
|
||||
return SecretKeyFactory.getInstance("PBEWithHmacSHA256AndAES_128")
|
||||
.generateSecret(keySpec);
|
||||
}
|
||||
|
||||
public static String encodeSecretKey(final SecretKey secretKey){
|
||||
return Base64.getEncoder().encodeToString(secretKey.getEncoded());
|
||||
}
|
||||
public static SecretKey decodeSecretKey(final String secretKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
|
||||
SecretKey keySpec = new SecretKeySpec(Base64.getDecoder().decode(secretKey), "AES");
|
||||
return keySpec;
|
||||
}
|
||||
|
||||
public static IvParameterSpec generateIV(byte[] iv){
|
||||
IvParameterSpec parameterSpec = new IvParameterSpec(iv);
|
||||
return parameterSpec;
|
||||
}
|
||||
}
|
||||
44
security/src/main/java/kr/pe/elex/examples/RSAKeys.java
Normal file
44
security/src/main/java/kr/pe/elex/examples/RSAKeys.java
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Examples for Java
|
||||
*
|
||||
* Copyright (c) 2021. Elex. All Rights Reserved.
|
||||
* https://www.elex-project.com/
|
||||
*/
|
||||
|
||||
package kr.pe.elex.examples;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.security.*;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.Base64;
|
||||
|
||||
@Slf4j
|
||||
public class RSAKeys {
|
||||
public static KeyPair generateKeyPair() throws NoSuchAlgorithmException {
|
||||
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
|
||||
keyPairGen.initialize(2048, new SecureRandom());
|
||||
return keyPairGen.generateKeyPair();
|
||||
}
|
||||
|
||||
public static String encodePrivateKey(final PrivateKey privateKey) {
|
||||
return Base64.getEncoder().encodeToString(privateKey.getEncoded());
|
||||
}
|
||||
|
||||
public static String encodePublicKey(final PublicKey publicKey) {
|
||||
return Base64.getEncoder().encodeToString(publicKey.getEncoded());
|
||||
}
|
||||
|
||||
public static PublicKey decodePublicKey(final String publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
|
||||
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKey));
|
||||
return KeyFactory.getInstance("RSA").generatePublic(keySpec);
|
||||
}
|
||||
|
||||
public static PrivateKey decodePrivateKey(final String privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
|
||||
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(privateKey));
|
||||
return KeyFactory.getInstance("RSA").generatePrivate(keySpec);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
* Examples for Java
|
||||
*
|
||||
* Copyright (c) 2021. Elex. All Rights Reserved.
|
||||
* https://www.elex-project.com/
|
||||
*/
|
||||
|
||||
package kr.pe.elex.examples;
|
||||
40
security/src/test/java/kr/pe/elex/examples/AESKeysTest.java
Normal file
40
security/src/test/java/kr/pe/elex/examples/AESKeysTest.java
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2024. Elex. All Rights Reesrved.
|
||||
* https://www.elex-project.com/
|
||||
*/
|
||||
|
||||
package kr.pe.elex.examples;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.util.Random;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class AESKeysTest {
|
||||
|
||||
@Test
|
||||
void test() throws NoSuchAlgorithmException, InvalidKeySpecException {
|
||||
SecretKey secretKey = AESKeys.generateSecretKey();
|
||||
|
||||
String base64SecretKey = AESKeys.encodeSecretKey(secretKey);
|
||||
|
||||
SecretKey secretKey1 = AESKeys.decodeSecretKey(base64SecretKey);
|
||||
|
||||
assertEquals(secretKey, secretKey1);
|
||||
}
|
||||
@Test
|
||||
void test1() throws NoSuchAlgorithmException, InvalidKeySpecException {
|
||||
byte[] salt = new byte[8];
|
||||
new Random().nextBytes(salt);
|
||||
SecretKey secretKey = AESKeys.generateSecretKey("Hello".toCharArray(), salt, 10);
|
||||
|
||||
SecretKey secretKey1 = AESKeys.generateSecretKey("Hello".toCharArray(), salt, 10);
|
||||
|
||||
assertEquals(secretKey, secretKey1);
|
||||
}
|
||||
}
|
||||
21
security/src/test/java/kr/pe/elex/examples/SampleTest.java
Normal file
21
security/src/test/java/kr/pe/elex/examples/SampleTest.java
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Examples for Java
|
||||
*
|
||||
* Copyright (c) 2021. Elex. All Rights Reserved.
|
||||
* https://www.elex-project.com/
|
||||
*/
|
||||
|
||||
package kr.pe.elex.examples;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
|
||||
class SampleTest {
|
||||
|
||||
@Test
|
||||
void test() throws NoSuchAlgorithmException, InvalidKeySpecException {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -15,5 +15,5 @@ include(
|
||||
"xml", "jackson", "jsoup", "markdown", "network", "httpd",
|
||||
"properties", "serial-io",
|
||||
"mustache", "thymeleaf", "locale", "quartz", "sysinfo",
|
||||
"imaging", "stream", "sound", "midi", "gson"
|
||||
"imaging", "stream", "sound", "midi", "gson", "security"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user