diff --git a/web3-credential-server/build/resources/main/application.properties b/web3-credential-server/build/resources/main/application.properties index 982f8e6..78fac83 100644 --- a/web3-credential-server/build/resources/main/application.properties +++ b/web3-credential-server/build/resources/main/application.properties @@ -66,5 +66,7 @@ cloud.aws.stack.auto=false passport.client-secret= passport.public-key-str= +#RSA ???? ??? ? ???(Public Key) +rsa.public-key= diff --git a/web3-credential-server/build/resources/main/data.sql b/web3-credential-server/build/resources/main/data.sql index 0910a80..c8e7302 100644 --- a/web3-credential-server/build/resources/main/data.sql +++ b/web3-credential-server/build/resources/main/data.sql @@ -1,14 +1,12 @@ INSERT INTO users (email, password) VALUES ('pjhcsols@naver.com', '$2a$10$ENYqGvZ3p6LvtsBnRWINSOJHKlMt1Ykgb3.jCnoKkrhMihviXhkDu'), - ('exampleuser@example.com', '$2a$10$EXAMPLEHASHFORUSERPASSWORD'), - ('3751271433', '$2a$10$ENYqGvZ3p6LvtsBnRWINSOJHKlMt1Ykgb3.jCnoKkrhMihviXhkDu'); + ('exampleuser@example.com', '$2a$10$EXAMPLEHASHFORUSERPASSWORD'); INSERT INTO wallets (user_id, private_key, public_key) VALUES - (1, 'privateKeyForUser1', 'publicKeyForUser1'), - (2, 'privateKeyForUser2', 'publicKeyForUser2'), - (3, 'privateKeyForUser3', 'publicKeyForUser3'); + (1, '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'), + (2, 'privateKeyForUser2', 'publicKeyForUser2'); INSERT INTO wallet_pdf_urls (wallet_id, certificate_type, pdf_url) VALUES @@ -16,3 +14,7 @@ VALUES (1, '여권_1', 'https://s3.ap-northeast-2.amazonaws.com/basilium-product-bucket/1_passport_certification.pdf'), (2, '재학증_2', null); +INSERT INTO wallet_pdf_hash (wallet_id, certificate_type, pdf_hash) +VALUES + (1, '재학증_1', '82a9ba18e4f8c3bbf64b9500ecd8b7701371db05f32887fc2835447d66cfa8e8'), + (1, '여권_1', 'd2c70bf0b298e152e95649cfeb21c4d9a698b052ee62c0c70d9aa9b4ac6f6325'); diff --git a/web3-credential-server/build/resources/main/schema.sql b/web3-credential-server/build/resources/main/schema.sql index fc3105f..181a6f1 100644 --- a/web3-credential-server/build/resources/main/schema.sql +++ b/web3-credential-server/build/resources/main/schema.sql @@ -1,4 +1,5 @@ DROP TABLE IF EXISTS wallet_pdf_urls; +DROP TABLE IF EXISTS wallet_pdf_hash; DROP TABLE IF EXISTS wallets; DROP TABLE IF EXISTS users; @@ -11,8 +12,8 @@ CREATE TABLE users ( CREATE TABLE wallets ( id BIGINT AUTO_INCREMENT PRIMARY KEY, user_id BIGINT NOT NULL, - private_key VARCHAR(255) NOT NULL, - public_key VARCHAR(255), + private_key TEXT NOT NULL, -- TEXT로 변경 + public_key TEXT NOT NULL, -- TEXT로 변경 FOREIGN KEY (user_id) REFERENCES users(id) ); @@ -22,4 +23,12 @@ CREATE TABLE wallet_pdf_urls ( pdf_url VARCHAR(255), PRIMARY KEY (wallet_id, certificate_type), FOREIGN KEY (wallet_id) REFERENCES wallets(id) -); \ No newline at end of file +); + +CREATE TABLE wallet_pdf_hash ( + wallet_id BIGINT, + certificate_type VARCHAR(255), + pdf_hash VARCHAR(255), + PRIMARY KEY (wallet_id, certificate_type), + FOREIGN KEY (wallet_id) REFERENCES wallets(id) +); diff --git a/web3-credential-server/build/tmp/compileJava/previous-compilation-data.bin b/web3-credential-server/build/tmp/compileJava/previous-compilation-data.bin index 87b096b..4abe152 100644 Binary files a/web3-credential-server/build/tmp/compileJava/previous-compilation-data.bin and b/web3-credential-server/build/tmp/compileJava/previous-compilation-data.bin differ diff --git a/web3-credential-server/src/main/java/web3/controller/wallet/WalletController.java b/web3-credential-server/src/main/java/web3/controller/wallet/WalletController.java index 46f8955..2e26948 100644 --- a/web3-credential-server/src/main/java/web3/controller/wallet/WalletController.java +++ b/web3-credential-server/src/main/java/web3/controller/wallet/WalletController.java @@ -13,6 +13,7 @@ import web3.service.wallet.WalletService; import web3.validation.LoginMember; +import java.security.NoSuchAlgorithmException; import java.util.List; import java.util.Optional; @@ -51,11 +52,12 @@ public ResponseEntity getMyWallet(@LoginMember User loginUser) { @ApiResponse(responseCode = "400", description = "잘못된 요청") } ) - public ResponseEntity createWallet(@LoginMember User loginUser) throws WalletAlreadyExistsException { + public ResponseEntity createWallet(@LoginMember User loginUser) throws WalletAlreadyExistsException, NoSuchAlgorithmException { Wallet wallet = walletService.createWallet(loginUser); return new ResponseEntity<>(wallet, HttpStatus.CREATED); } + @PutMapping("/{id}") @Operation( summary = "지갑 업데이트", @@ -68,9 +70,8 @@ public ResponseEntity createWallet(@LoginMember User loginUser) throws W public ResponseEntity updateWallet( @PathVariable Long id, @RequestParam String privateKey, - @RequestParam String publicKey, - @RequestParam String address) { - Wallet updatedWallet = walletService.updateWallet(id, privateKey, publicKey, address); + @RequestParam String publicKey) { + Wallet updatedWallet = walletService.updateWallet(id, privateKey, publicKey); return ResponseEntity.ok(updatedWallet); } diff --git a/web3-credential-server/src/main/java/web3/domain/wallet/Wallet.java b/web3-credential-server/src/main/java/web3/domain/wallet/Wallet.java index 84383d5..a21f36b 100644 --- a/web3-credential-server/src/main/java/web3/domain/wallet/Wallet.java +++ b/web3-credential-server/src/main/java/web3/domain/wallet/Wallet.java @@ -2,7 +2,15 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import jakarta.persistence.*; +import lombok.Getter; import web3.domain.user.User; + +import java.security.KeyFactory; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.Base64; import java.util.HashMap; import java.util.Map; @@ -25,67 +33,101 @@ public class Wallet { @Column(name = "pdf_url") private Map pdfUrls = new HashMap<>(); - // RSA 암호화를 위한 키 - //uuid를 넣어서 RSA 암호화 할때 같이 사용, 메타데이터 업로드 및 가져올때 디코딩 - @JsonIgnore + //@JsonIgnore @Column(name = "private_key", nullable = false) - private String privateKey; // 메타데이터 디코딩 용 + private String privateKey; // value 복호화 - @Column(name = "public_key", nullable = true) - private String publicKey; //인증서 해시값 저장 + @Column(name = "public_key", nullable = false) + private String publicKey; // value 암호화 - //공동 인증서 정보 추가? + @ElementCollection + @CollectionTable(name = "wallet_pdf_hash", joinColumns = @JoinColumn(name = "wallet_id")) + @MapKeyColumn(name = "certificate_type") + @Column(name = "pdf_hash") + private Map pdfHash = new HashMap<>(); //PDF 해시 비교로직 구성 + // 기본 생성자 protected Wallet() {} + // 생성자 public Wallet(User user, String privateKey, String publicKey) { this.user = user; this.privateKey = privateKey; this.publicKey = publicKey; } - public Wallet(User user, String privateKey) { - this.user = user; - this.privateKey = privateKey; + public Map getPdfUrls() { + return pdfUrls; } - public void updateWallet(String privateKey, String publicKey) { - this.privateKey = privateKey; - this.publicKey = publicKey; + public Long getId() { + return id; } - public void addToPublicKey(String publicKey){ - this.publicKey = publicKey; + public User getUser() { + return user; } - //key(재학증_1):value(pdfUrl) 로 디비에 저장 - public void updatePdfUrl(String certificateType, String pdfUrl) { - this.pdfUrls.put(certificateType, pdfUrl); + public String getPrivateKey() { + return privateKey; // String 반환 } - // 인증서 타입에 따라 PDF URL 가져오기 - public String getPdfUrl(String certificateType) { - return this.pdfUrls.get(certificateType); + public String getPublicKey() { + return publicKey; // String 반환 } - public Map getPdfUrls() { - return pdfUrls; + public Map getPdfHash() { + return pdfHash; } - public Long getId() { - return id; + @JsonIgnore // 이 메서드는 JSON 직렬화에서 제외합니다. + public PublicKey getPublicKeyDecoder() { + return convertKey(publicKey, true); } - public User getUser() { - return user; + @JsonIgnore // 이 메서드는 JSON 직렬화에서 제외합니다. + public PrivateKey getPrivateKeyDecoder() { + return convertKey(privateKey, false); } - public String getPrivateKey() { - return privateKey; + private T convertKey(String key, boolean isPublicKey) { + try { + byte[] keyBytes = Base64.getDecoder().decode(key); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + if (isPublicKey) { + X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes); + return (T) keyFactory.generatePublic(spec); + } else { + PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes); + return (T) keyFactory.generatePrivate(spec); + } + } catch (Exception e) { + String keyType = isPublicKey ? "공개키" : "개인키"; + throw new RuntimeException(keyType + " 변환 중 오류 발생", e); + } } - public String getPublicKey() { - return publicKey; + public void updateWallet(String privateKey, String publicKey) { + this.privateKey = privateKey; + this.publicKey = publicKey; + } + + public void addToPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public void updatePdfHash(String certificateType, String pdfHash) { + this.pdfHash.put(certificateType, pdfHash); + } + + // key(재학증_1):value(pdfUrl) 로 디비에 저장 + public void updatePdfUrl(String certificateType, String pdfUrl) { + this.pdfUrls.put(certificateType, pdfUrl); + } + + // 인증서 타입에 따라 PDF URL 가져오기 + public String getPdfUrl(String certificateType) { + return this.pdfUrls.get(certificateType); } @Override @@ -109,7 +151,8 @@ public String toString() { ", privateKey='" + privateKey + '\'' + ", publicKey='" + publicKey + '\'' + ", pdfUrls=" + pdfUrls + + ", pdfHash=" + pdfHash + '}'; } -} \ No newline at end of file +} diff --git a/web3-credential-server/src/main/java/web3/properties/RsaProperties.java b/web3-credential-server/src/main/java/web3/properties/RsaProperties.java new file mode 100644 index 0000000..d30ceff --- /dev/null +++ b/web3-credential-server/src/main/java/web3/properties/RsaProperties.java @@ -0,0 +1,10 @@ +package web3.properties; + +import org.springframework.boot.context.properties.ConfigurationProperties; + + +@ConfigurationProperties(prefix = "rsa") +public record RsaProperties ( + String publicKey //사용안함 +){ +} diff --git a/web3-credential-server/src/main/java/web3/service/Identity/IdentityService.java b/web3-credential-server/src/main/java/web3/service/Identity/IdentityService.java index d4e1c13..867d8de 100644 --- a/web3-credential-server/src/main/java/web3/service/Identity/IdentityService.java +++ b/web3-credential-server/src/main/java/web3/service/Identity/IdentityService.java @@ -16,6 +16,7 @@ import software.amazon.awssdk.services.s3.model.*; import web3.domain.wallet.Wallet; import web3.exception.S3.S3UploadException; +import web3.properties.RsaProperties; import web3.properties.S3Properties; import web3.repository.wallet.WalletRepository; @@ -27,26 +28,50 @@ import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; import java.time.LocalDateTime; import java.util.*; +import java.util.stream.Collectors; + import com.fasterxml.jackson.core.type.TypeReference; import web3.service.dto.Identity.PassportCertificationDto; import web3.service.dto.Identity.StudentCertificationDto; +import javax.crypto.Cipher; + @Service @Slf4j public class IdentityService { private final S3Properties s3Properties; + private final RsaProperties rsaProperties; private final S3Client s3Client; private final WalletRepository walletRepository; @Autowired - public IdentityService(S3Properties s3Properties, WalletRepository walletRepository) { + public IdentityService(S3Properties s3Properties, WalletRepository walletRepository, RsaProperties rsaProperties) { this.s3Properties = s3Properties; this.s3Client = s3Properties.getS3Client(); this.walletRepository = walletRepository; + this.rsaProperties = rsaProperties; + } + + // RSA 암호화 로직 메서드 + private String encryptMetadata(String metadata, PublicKey publicKey) throws Exception { + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.ENCRYPT_MODE, publicKey); + byte[] encryptedBytes = cipher.doFinal(metadata.getBytes(StandardCharsets.UTF_8)); + return Base64.getEncoder().encodeToString(encryptedBytes); + } + + // RSA 복호화 로직 메서드 + private String decryptMetadata(String encryptedMetadata, PrivateKey privateKey) throws Exception { + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.DECRYPT_MODE, privateKey); + byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedMetadata)); + return new String(decryptedBytes, StandardCharsets.UTF_8); } @Transactional @@ -71,8 +96,20 @@ public void registerStudentCertification(Long walletId, StudentCertificationDto throw new RuntimeException("파일 처리 중 오류 발생", e); } + // RSA 암호화 및 복호화 키 설정 + PublicKey publicKey = wallet.getPublicKeyDecoder(); // 공개키 객체로 변환 + + String encryptedMetadata; + // 공개키로 암호화 + try { + encryptedMetadata = encryptMetadata(metadataString, publicKey); + } catch (Exception e) { + throw new RuntimeException("메타데이터 암호화 중 오류 발생", e); + } + HashMap metadata = new HashMap<>(); - metadata.put(metadataKey, metadataString); + + metadata.put(metadataKey, encryptedMetadata); log.info("metadata = {}", metadata); uploadToS3(fileName, metadata, result); @@ -80,8 +117,7 @@ public void registerStudentCertification(Long walletId, StudentCertificationDto // PDF 파일 해시값 생성 String pdfHash = generatePdfHash(result); // 지갑에 해시값 추가 - wallet.addToPublicKey(pdfHash); // addToPublicKey 메서드는 Wallet 엔티티 내에서 정의 - + wallet.updatePdfHash(metadataKey, pdfHash); wallet.updatePdfUrl(metadataKey, getPdfUrl(fileName)); walletRepository.saveAndFlush(wallet); } @@ -119,9 +155,20 @@ public void registerPassportCertification(Long walletId, PassportCertificationDt throw new RuntimeException("파일 처리 중 오류 발생", e); } - // 메타데이터를 HashMap에 저장합니다. + // RSA 암호화 및 복호화 키 설정 + PublicKey publicKey = wallet.getPublicKeyDecoder(); // 공개키 객체로 변환 + + String encryptedMetadata; + // 공개키로 암호화 + try { + encryptedMetadata = encryptMetadata(metadataString, publicKey); + } catch (Exception e) { + throw new RuntimeException("메타데이터 암호화 중 오류 발생", e); + } + HashMap metadata = new HashMap<>(); - metadata.put(metadataKey, metadataString); + + metadata.put(metadataKey, encryptedMetadata); log.info("metadata = {}", metadata); uploadToS3(fileName, metadata, result); @@ -129,7 +176,7 @@ public void registerPassportCertification(Long walletId, PassportCertificationDt // PDF 파일 해시값 생성 String pdfHash = generatePdfHash(result); // 지갑에 해시값 추가 - wallet.addToPublicKey(pdfHash); // addToPublicKey 메서드는 Wallet 엔티티 내에서 정의 + wallet.updatePdfHash(metadataKey, pdfHash); wallet.updatePdfUrl(metadataKey, getPdfUrl(fileName)); walletRepository.saveAndFlush(wallet); } @@ -154,6 +201,44 @@ private String generatePdfHash(byte[] fileData) { } } + public List> getContentsForCertName(String pdfUrl, String certName, Long walletId) { + try { + // 파일 이름 추출 및 S3에서 메타데이터 가져오기 + String fileName = extractKeyFromUrl(pdfUrl); + GetObjectResponse getObjectResponse = s3Client.getObject(getGetObjectRequest(fileName)).response(); + + // 주어진 certName과 walletId에 해당하는 메타데이터 찾기 + String value = Optional.ofNullable( + decodeMetadata(getObjectResponse.metadata()).entrySet().stream() + .filter(entry -> entry.getKey().startsWith(certName + "_") && entry.getKey().endsWith(walletId.toString())) + .map(Map.Entry::getValue) + .findFirst() + .orElseThrow(() -> new RuntimeException("조건에 맞는 메타데이터가 없습니다.")) + ).orElseThrow(); + + log.info("[RSA 디코딩 및 JSON 파싱 진행중]"); + log.info("암호화된 메타데이터: {}", value); + + // 월렛에서 개인키 가져오기 + PrivateKey privateKey = walletRepository.findById(walletId) + .map(Wallet::getPrivateKeyDecoder) + .orElseThrow(() -> new RuntimeException("Wallet not found")); + + String decryptedValue = decryptMetadata(value, privateKey); + log.info("복호화된 메타데이터: {}", decryptedValue); + log.info("[메타데이터 전송 완료]"); + // JSON 파싱 후 (key, value) 형태로 변환하여 리스트로 반환 + return new ObjectMapper().readValue(decryptedValue, new TypeReference>() {}) + .entrySet().stream() + .map(entry -> new AbstractMap.SimpleEntry<>(entry.getKey(), entry.getValue().toString())) + .collect(Collectors.toList()); + + } catch (Exception e) { + log.error("오류 발생: {}", e.getMessage(), e); + return Collections.emptyList(); // 예외 발생 시 빈 리스트 반환 + } + } + //pdf 병합 로직 private byte[] handlePdfProcessing(String destination, MultipartFile file) throws IOException { byte[] first = (destination != null) ? getBytes(destination) : null; @@ -395,7 +480,7 @@ public HashMap getCertList(String pdfUrl) { } @Transactional - public HashMap getPdfMetadata( String pdfUrl) { + public HashMap getPdfMetadata(String pdfUrl) { HashMap metadata; String fileName = extractKeyFromUrl(pdfUrl); @@ -463,51 +548,6 @@ public Set getCertNames(String pdfUrl) { return certNames; // Set 형태로 반환 } - - public List> getContentsForCertName(String pdfUrl, String certName, Long walletId) { - String fileName = extractKeyFromUrl(pdfUrl); - GetObjectRequest getRequest = getGetObjectRequest(fileName); - GetObjectResponse getObjectResponse = s3Client.getObject(getRequest).response(); - String value = null; - List> tuples = new ArrayList<>(); - - // 메타데이터 디코딩 - Map metadata = decodeMetadata(getObjectResponse.metadata()); - - // 주어진 certName과 walletId에 해당하는 메타데이터 찾기 - for (String key : metadata.keySet()) { - if (key.startsWith(certName + "_") && key.endsWith(walletId.toString())) { - value = metadata.get(key); - break; - } - } - - // value 값이 없는 경우 null 처리 - if (value == null) { - return tuples; // 빈 리스트 반환 - } - - // JSON 파싱을 위해 ObjectMapper 사용 - try { - ObjectMapper objectMapper = new ObjectMapper(); - // JSON 형식으로 저장된 value를 Map으로 변환 - Map parsedJson = objectMapper.readValue(value, new TypeReference>() {}); - - // Map의 각 항목을 (key, value) 형태로 변환하여 리스트에 추가 - for (Map.Entry entry : parsedJson.entrySet()) { - tuples.add(new AbstractMap.SimpleEntry<>(entry.getKey(), entry.getValue().toString())); - } - - } catch (Exception e) { - e.printStackTrace(); - // 오류 발생 시 빈 리스트 반환 - return tuples; - } - - System.out.println("tuples = " + tuples); - return tuples; - } - private GetObjectRequest getGetObjectRequest(String fileName) { GetObjectRequest getRequest = GetObjectRequest.builder() .bucket(s3Properties.getS3BucketName()) diff --git a/web3-credential-server/src/main/java/web3/service/kakao/KakaoService.java b/web3-credential-server/src/main/java/web3/service/kakao/KakaoService.java index 7dd0540..b585e11 100644 --- a/web3-credential-server/src/main/java/web3/service/kakao/KakaoService.java +++ b/web3-credential-server/src/main/java/web3/service/kakao/KakaoService.java @@ -209,7 +209,7 @@ public Map sendWalletInfo(User user, String accessToken) { Map response = new HashMap<>(); response.put("userId", user.getId()); response.put("walletId", wallet.getId()); - response.put("privateKey", wallet.getPrivateKey()); + //response.put("privateKey", wallet.getPrivateKey()); response.put("publicKey", wallet.getPublicKey()); logger.info("지갑 정보 전송 완료: {}", response); @@ -239,8 +239,9 @@ private void sendKakaoWalletInfo(User user, String accessToken, Wallet wallet) { private String createWalletTemplateObject(User user, Wallet wallet) { Map templateObject = new HashMap<>(); templateObject.put("object_type", "text"); - templateObject.put("text", String.format("지갑 정보\n이메일: %s\nPrivate Key: %s\nPublic Key: %s\n인증서: %s", - user.getEmail(), wallet.getPrivateKey(), wallet.getPublicKey(), wallet.getPdfUrls())); + //templateObject.put("text", String.format("지갑 정보\n이메일: %s\nPrivate Key: %s\nPublic Key: %s\n인증서: %s",user.getEmail(), wallet.getPrivateKey(), wallet.getPublicKey(), wallet.getPdfUrls())); + templateObject.put("text", String.format("지갑 정보\n이메일: %s\nPublic Key: %s\n인증서: %s", + user.getEmail(), wallet.getPublicKey(), wallet.getPdfUrls())); templateObject.put("link", Map.of("web_url", "http://your-web-url.com")); try { diff --git a/web3-credential-server/src/main/java/web3/service/wallet/WalletService.java b/web3-credential-server/src/main/java/web3/service/wallet/WalletService.java index 50fbd7d..f98c2c1 100644 --- a/web3-credential-server/src/main/java/web3/service/wallet/WalletService.java +++ b/web3-credential-server/src/main/java/web3/service/wallet/WalletService.java @@ -9,6 +9,8 @@ import web3.exception.wallet.WalletPrivateKeyNotEqualsException; import web3.repository.wallet.WalletRepository; +import java.security.*; +import java.util.Base64; import java.util.List; import java.util.Optional; import java.util.UUID; @@ -24,15 +26,22 @@ public WalletService(WalletRepository walletRepository) { this.walletRepository = walletRepository; } - //지갑 생성 - public Wallet createWallet(User user) throws WalletAlreadyExistsException { + public Wallet createWallet(User user) throws WalletAlreadyExistsException, NoSuchAlgorithmException { Optional existingWallet = walletRepository.findByUser(user); if (existingWallet.isPresent()) { throw new WalletAlreadyExistsException("User already has a wallet"); } - //pk에 uuid - String privateKey = UUID.randomUUID().toString(); - Wallet wallet = new Wallet(user, privateKey); + + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); + keyPairGenerator.initialize(2048, new SecureRandom()); + KeyPair keyPair = keyPairGenerator.generateKeyPair(); + + // 공개키와 개인키를 PEM 형식의 문자열로 변환 + String publicKeyString = Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded()); + String privateKeyString = Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded()); + + // 지갑 생성 + Wallet wallet = new Wallet(user, privateKeyString, publicKeyString); return walletRepository.save(wallet); } @@ -47,7 +56,7 @@ public Optional getWalletByUser(User user) { } // 지갑 업데이트,더티체킹 update 사용안함 - public Wallet updateWallet(Long id, String privateKey, String publicKey, String address) { + public Wallet updateWallet(Long id, String privateKey, String publicKey) { Wallet existingWallet = walletRepository.findById(id) .orElseThrow(() -> new RuntimeException("Wallet not found")); existingWallet.updateWallet(privateKey, publicKey); @@ -76,8 +85,5 @@ public Wallet getCertainWallet(Long id, String privateKey) throws WalletPrivateK return wallet; } - private boolean matchPrivateKey(String privateKey, Wallet wallet) { - return wallet.getPrivateKey().equals(privateKey); - } } diff --git a/web3-credential-server/src/main/resources/application.properties b/web3-credential-server/src/main/resources/application.properties index 982f8e6..78fac83 100644 --- a/web3-credential-server/src/main/resources/application.properties +++ b/web3-credential-server/src/main/resources/application.properties @@ -66,5 +66,7 @@ cloud.aws.stack.auto=false passport.client-secret= passport.public-key-str= +#RSA ???? ??? ? ???(Public Key) +rsa.public-key= diff --git a/web3-credential-server/src/main/resources/data.sql b/web3-credential-server/src/main/resources/data.sql index 0910a80..c8e7302 100644 --- a/web3-credential-server/src/main/resources/data.sql +++ b/web3-credential-server/src/main/resources/data.sql @@ -1,14 +1,12 @@ INSERT INTO users (email, password) VALUES ('pjhcsols@naver.com', '$2a$10$ENYqGvZ3p6LvtsBnRWINSOJHKlMt1Ykgb3.jCnoKkrhMihviXhkDu'), - ('exampleuser@example.com', '$2a$10$EXAMPLEHASHFORUSERPASSWORD'), - ('3751271433', '$2a$10$ENYqGvZ3p6LvtsBnRWINSOJHKlMt1Ykgb3.jCnoKkrhMihviXhkDu'); + ('exampleuser@example.com', '$2a$10$EXAMPLEHASHFORUSERPASSWORD'); INSERT INTO wallets (user_id, private_key, public_key) VALUES - (1, 'privateKeyForUser1', 'publicKeyForUser1'), - (2, 'privateKeyForUser2', 'publicKeyForUser2'), - (3, 'privateKeyForUser3', 'publicKeyForUser3'); + (1, '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'), + (2, 'privateKeyForUser2', 'publicKeyForUser2'); INSERT INTO wallet_pdf_urls (wallet_id, certificate_type, pdf_url) VALUES @@ -16,3 +14,7 @@ VALUES (1, '여권_1', 'https://s3.ap-northeast-2.amazonaws.com/basilium-product-bucket/1_passport_certification.pdf'), (2, '재학증_2', null); +INSERT INTO wallet_pdf_hash (wallet_id, certificate_type, pdf_hash) +VALUES + (1, '재학증_1', '82a9ba18e4f8c3bbf64b9500ecd8b7701371db05f32887fc2835447d66cfa8e8'), + (1, '여권_1', 'd2c70bf0b298e152e95649cfeb21c4d9a698b052ee62c0c70d9aa9b4ac6f6325'); diff --git a/web3-credential-server/src/main/resources/schema.sql b/web3-credential-server/src/main/resources/schema.sql index fc3105f..181a6f1 100644 --- a/web3-credential-server/src/main/resources/schema.sql +++ b/web3-credential-server/src/main/resources/schema.sql @@ -1,4 +1,5 @@ DROP TABLE IF EXISTS wallet_pdf_urls; +DROP TABLE IF EXISTS wallet_pdf_hash; DROP TABLE IF EXISTS wallets; DROP TABLE IF EXISTS users; @@ -11,8 +12,8 @@ CREATE TABLE users ( CREATE TABLE wallets ( id BIGINT AUTO_INCREMENT PRIMARY KEY, user_id BIGINT NOT NULL, - private_key VARCHAR(255) NOT NULL, - public_key VARCHAR(255), + private_key TEXT NOT NULL, -- TEXT로 변경 + public_key TEXT NOT NULL, -- TEXT로 변경 FOREIGN KEY (user_id) REFERENCES users(id) ); @@ -22,4 +23,12 @@ CREATE TABLE wallet_pdf_urls ( pdf_url VARCHAR(255), PRIMARY KEY (wallet_id, certificate_type), FOREIGN KEY (wallet_id) REFERENCES wallets(id) -); \ No newline at end of file +); + +CREATE TABLE wallet_pdf_hash ( + wallet_id BIGINT, + certificate_type VARCHAR(255), + pdf_hash VARCHAR(255), + PRIMARY KEY (wallet_id, certificate_type), + FOREIGN KEY (wallet_id) REFERENCES wallets(id) +);