package small.bit.coin.custom;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;
import java.security.Signature;
import java.security.SignatureException;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Base64;
import small.bit.coin.util.PemFileObject;
public class EccInstanceObject {
public static void main(String [] args)
{
// 바운시 캐슬의 암호화 라이브러리를 사용하도록 설정.
Security.addProvider(new BouncyCastleProvider());
// 타원 곡선 객체를 생성해 개인키와 공개키를 각각 private.pem, public.pem으로 저장.
EccInstanceObject eccObject = new EccInstanceObject("private.pem", "public.pem");
//eccObject.callOne(eccObject);
try {
eccObject.callTwo(eccObject);
} catch (InvalidKeyException | NoSuchAlgorithmException | InvalidKeySpecException | SignatureException
| IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void callOne(EccInstanceObject eccObject)
{
try {
eccObject.generate();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// 파일로 저장한 개인키와 공개키를 다시 프로그램으로 불러옵니다.
try {
PrivateKey privateKey = eccObject.readPrivateKeyFromPemFile("private.pem");
} catch (NoSuchAlgorithmException | InvalidKeySpecException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
PublicKey publicKey = eccObject.readPublicKeyFromPemFile("public.pem");
} catch (NoSuchAlgorithmException | InvalidKeySpecException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
String strPrivateFileName;
String strPublicFileName;
public EccInstanceObject(String pPrivateKeyFileName, String pPublicKeyFileName)
{
strPrivateFileName = pPrivateKeyFileName;
strPublicFileName = pPublicKeyFileName;
// 바운시 캐슬의 암호화 라이브러리를 사용하도록 설정.
Security.addProvider(new BouncyCastleProvider());
}
public void callTwo(EccInstanceObject eccObject) throws FileNotFoundException, NoSuchAlgorithmException, InvalidKeySpecException, IOException, InvalidKeyException, SignatureException
{
try {
//두 쌍의 키를 생성해 파일 형태로 저장
eccObject.generate("private1.pem", "public1.pem");
eccObject.generate("private2.pem", "public2.pem");
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// 파일로 저장한 개인키와 공개키를 다시 프로그램으로 불러옵니다.
PrivateKey privateKey1=null;
PublicKey publicKey1=null;
privateKey1 = eccObject.readPrivateKeyFromPemFile("private1.pem");
publicKey1 = eccObject.readPublicKeyFromPemFile("public1.pem");
PrivateKey privateKey2=null;
PublicKey publicKey2=null;
privateKey2 = eccObject.readPrivateKeyFromPemFile("private2.pem");
publicKey2 = eccObject.readPublicKeyFromPemFile("public2.pem");
Signature signature=null;
String strAlgorithm = "SHA1withECDSA";
signature = Signature.getInstance(strAlgorithm);
// 개인키 1을 이용해 암호화(서명)합니다.
signature.initSign(privateKey1);
String strChar = "UTF-8";
String text = "평문입니다.";
System.out.println("평문 정보: " + text);
byte[] byteText = text.getBytes(strChar);
// 평문 데이터를 암호화하여 서명한 데이터를 출력합니다.
signature.update(byteText);
byte[] byteSignature = signature.sign();
System.out.println("서명된 값: 0x" + (new BigInteger(1, byteSignature).toString(16)).toUpperCase());
Signature signatureTwo;
signatureTwo = Signature.getInstance(strAlgorithm);
// 검증할 때는 공개키 2를 이용해 복호화를 수행합니다.
// signatureTwo.initVerify(publicKey1); //true
signatureTwo.initVerify(publicKey2); //false
signatureTwo.update(byteText);
boolean result = signatureTwo.verify(byteSignature);
// 개인키와 매칭되는 공개키가 아니므로 복호화에 실패합니다.
System.out.println("신원 검증: " + result);
}
//세부 알고리즘으로 sect163k1을 이용
private final String STR_ARGORITHM = "sect163k1";
//바운시 캐슬의 타원 곡션 표준 알고리즘(ECDSA)를 사용
private final String STR_STD_ARGORLTHM = "ECDSA";
//알고리즘 공금자정보
private final String STR_STD_PROVIDER = "BC";
//PK에 대한 설명
private final String STR_PRIVATE_DESC = "EC PRIVATE KEY";
//공개키에 대한 설명
private final String STR_PUBLIC_DESC = "EC PUBLIC KEY";
//private 시작을 알리는 내용
private final String STR_PRIVATE_BEGIN = "-----BEGIN EC PRIVATE KEY-----";
//private 종료를 알리는 내용
private final String STR_PRIVATE_END = "-----END EC PRIVATE KEY-----";
//public 시작을 알리는 내용
private final String STR_PUBLIC_BEGIN = "-----BEGIN EC PUBLIC KEY-----";
//public 종료를 알리는 내용
private final String STR_PUBLIC_END = "-----END EC PUBLIC KEY-----";
private final String STR_EMPTY = "";
//개인키와 공개키를 생성하기위한 Object
KeyPairGenerator generator;
//타원 곡선의 알고리즘 생성 Object
ECGenParameterSpec eCGenParameterSpec;
//키쌍을 생성
KeyPair keyPair;
//개인키(비밀키)
PrivateKey privateKey;
//공개키
PublicKey publicKey;
private String sPrivateKeyName="";
private String sPublicKeyName="";
//개이키와 공개키를 생성하여 파일에 저장하는 기능
public void generate () throws Exception
{
generate (strPrivateFileName, strPublicFileName);
}
//개이키와 공개키를 생성하여 파일에 저장하는 기능
public void generate (String pPrivateKeyName, String pPublicKeyName) throws Exception
{
//바운시 캐슬의 타원 곡션 표준 알고리즘(ECDSA)를 사용
generator = KeyPairGenerator.getInstance(STR_STD_ARGORLTHM, STR_STD_PROVIDER);
//타원 곡선의 세부 알고리즈으로 sect163k1을 사용
eCGenParameterSpec = new ECGenParameterSpec(STR_ARGORITHM);
//키생성을 위한 알고리즘과 인자 초기화
generator.initialize(eCGenParameterSpec, new SecureRandom());
//해당 알고리즘으로 무작위(랜덤)의 키 한 쌍을 생성합니다.
keyPair = generator.generateKeyPair();
System.out.println("암호화 키 한쌍 생성");
//공개키와 개인키를 추출
publicKey = keyPair.getPublic();
privateKey = keyPair.getPrivate();
sPrivateKeyName=pPrivateKeyName;
sPublicKeyName =pPublicKeyName;
// 개인키와 공개키를 특정한 파일 이름으로 저장
writePemFile( STR_PRIVATE_DESC, privateKey , pPrivateKeyName);
writePemFile( STR_PUBLIC_DESC , publicKey , pPublicKeyName);
}
private String getPrivateKeyName()
{
return sPrivateKeyName;
}
private String getPublicKeyName()
{
return sPublicKeyName;
}
// PemFileObject 클래스를 이용해 생성된 암호키를 파일로 저장하는 함수
private void writePemFile(String pDescription, Key pKey, String pFileName) throws FileNotFoundException, IOException
{
//PemObject 와 PemWriter를 이용하여 Key를 저장하는 Object
PemFileObject pemFileObject = new PemFileObject(pDescription,pKey);
pemFileObject.write(pFileName);
System.out.println(String.format("EC 암호키 %s을(를) %s 파일로 내보냈습니다.", pDescription, pFileName));
}
public PrivateKey readPrivateKeyFromPemFile(String pPrivateKeyPemFile)
throws FileNotFoundException , IOException, NoSuchAlgorithmException, InvalidKeySpecException
{
if(pPrivateKeyPemFile==null || STR_EMPTY.equals(pPrivateKeyPemFile.trim())) pPrivateKeyPemFile = getPrivateKeyName();
String strContext = readStringFromFile(pPrivateKeyPemFile);
System.out.println("EC 개인키를 " + pPrivateKeyPemFile + "로부터 불러왔습니다.");
System.out.print(strContext);
//파일에 입력되어 있는 설명 구문을 제거
strContext = strContext.replaceAll(STR_PRIVATE_BEGIN,STR_EMPTY);
strContext = strContext.replaceAll(STR_PRIVATE_END,STR_EMPTY);
//PEM파일은 Base64로 incoding 되어 있어 decoding 해서 read
byte[] byteDecoded = Base64.decode(strContext);
PKCS8EncodedKeySpec pKCS8EncodedKeySpec = new PKCS8EncodedKeySpec(byteDecoded);
KeyFactory keyFactory = KeyFactory.getInstance(STR_STD_ARGORLTHM);
PrivateKey privateKey = keyFactory.generatePrivate(pKCS8EncodedKeySpec);
return privateKey;
}
public PublicKey readPublicKeyFromPemFile(String pPublicKeyPemFile) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException
{
if(pPublicKeyPemFile==null || STR_EMPTY.equals(pPublicKeyPemFile.trim())) pPublicKeyPemFile = getPublicKeyName();
String strContext = readStringFromFile(pPublicKeyPemFile);
System.out.println("EC 개인키를 " + pPublicKeyPemFile + "로부터 불러왔습니다.");
System.out.print(strContext);
//파일에 입력되어 있는 설명 구문을 제거
strContext = strContext.replaceAll(STR_PUBLIC_BEGIN,STR_EMPTY);
strContext = strContext.replaceAll(STR_PUBLIC_END,STR_EMPTY);
//PEM파일은 Base64로 incoding 되어 있어 decoding 해서 read
byte[] byteDecoded = Base64.decode(strContext);
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(byteDecoded);
KeyFactory keyFactory = KeyFactory.getInstance(STR_STD_ARGORLTHM);
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
return publicKey;
}
//문자열을 그대로 읽어오는 함수.
private String readStringFromFile(String pFileName) throws IOException
{
String strContext = "";
BufferedReader bufferReader = new BufferedReader(
new FileReader(pFileName));
try
{
String str="";
while((str=bufferReader.readLine()) !=null)
{
strContext += str + "\n";
}
}
finally
{
bufferReader.close();
}
return strContext;
}
}
================================================
package small.bit.coin.custom;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.Signature;
import java.security.SignatureException;
import java.security.spec.InvalidKeySpecException;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class IntegrityCheckObject {
public static void main(String[] args) {
// TODO Auto-generated method stub
// 타원 곡선 객체를 생성해 개인키와 공개키를 각각 private.pem, public.pem으로 저장.
EccInstanceObject eccInstanceObject = new EccInstanceObject("private.pem", "public.pem");
try {
eccInstanceObject.generate();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
IntegrityCheckObject integrityCheckObject = new IntegrityCheckObject(eccInstanceObject);
byte[] bytes = integrityCheckObject.getSignaturePrivate("123");
System.out.println(integrityCheckObject.compareIntegrityValue("12",bytes,"public.pem"));
}
private EccInstanceObject eccInstanceObject;
//개인키
private PrivateKey privateKey;
//공개키
private PublicKey publicKey;
private final String STR_EMPTY = "";
public IntegrityCheckObject(EccInstanceObject pEccInstanceObject)
{
// 바운시 캐슬의 암호화 라이브러리를 사용하도록 설정.
Security.addProvider(new BouncyCastleProvider());
eccInstanceObject = pEccInstanceObject;
}
//private key를 가지고 오는 기능
private void getPrivateKey() throws FileNotFoundException, NoSuchAlgorithmException, InvalidKeySpecException, IOException
{
privateKey = eccInstanceObject.readPrivateKeyFromPemFile(STR_EMPTY);
}
//서명을 할 수 있는 기능의 Object
private Signature signaturePrivate = null;
//서명에 사용하는 알고리즘
private final String STR_ALGORITHM = "SHA1withECDSA";
private final String STR_CHARSET = "UTF-8";
//private key로 서명한 byte 값을 보관하고 있음
private byte[] byteSignaturePrivate = null;
//입력값에 private 값을 가지고 서명
private void hasSignaturePrivate(String pPlanText) throws NoSuchAlgorithmException, FileNotFoundException, InvalidKeySpecException, IOException, InvalidKeyException, SignatureException
{
byte[] byteText = pPlanText.getBytes(STR_CHARSET);
signaturePrivate = Signature.getInstance(STR_ALGORITHM);
getPrivateKey();
// 개인키 1을 이용해 암호화(서명)합니다.
signaturePrivate.initSign(privateKey);
// 평문 데이터를 암호화하여 서명한 데이터를 출력합니다.
signaturePrivate.update(byteText);
byteSignaturePrivate = signaturePrivate.sign();
}
//서명 결과를 반환
public byte[] getSignaturePrivate(String pPlanText)
{
byte[] reByte=null;
try
{
hasSignaturePrivate(pPlanText);
reByte= byteSignaturePrivate;
}
catch(Exception e)
{
e.printStackTrace();
}
return reByte;
}
//public key를 가지고 오는 기능
private void getPublicKey(String pPublicKeyFile) throws FileNotFoundException, NoSuchAlgorithmException, InvalidKeySpecException, IOException
{
publicKey = eccInstanceObject.readPublicKeyFromPemFile(pPublicKeyFile);
}
//public key를 가지고 오기 위해서 파일명을 입력하는 기능을 제공
private PublicKey putPublicKeyFile(String pPublicKeyFile) throws FileNotFoundException, NoSuchAlgorithmException, InvalidKeySpecException, IOException
{
if(pPublicKeyFile ==null || STR_EMPTY.equals(pPublicKeyFile.trim()))
{
System.out.println(" PublicKeyFile is null ");
return null;
}
getPublicKey(pPublicKeyFile);
return publicKey;
}
//입력한 자료에 대해서 서명이 올바른지 혹인 하는 기능
public boolean compareIntegrityValue(String pPlanText, byte[] pByteSignaturePrivate ,String pPublicKeyFile)
{
boolean reBool = true;
try
{
PublicKey publicKey = putPublicKeyFile(pPublicKeyFile);
if(publicKey == null)
{
System.out.println(" PublicKey is null ");
reBool = false;
}
else
{
byte[] byteText = pPlanText.getBytes(STR_CHARSET);
Signature signature;
signature = Signature.getInstance(STR_ALGORITHM);
// 검증할 때는 공개키 2를 이용해 복호화를 수행합니다.
signature.initVerify(publicKey);
signature.update(byteText);
reBool = signature.verify(pByteSignaturePrivate);
}
}
catch(Exception e)
{
e.printStackTrace();
}
return reBool;
}
}
java.exe 와 javaw.exe 의 차이점 (0) | 2020.08.14 |
---|---|
SelectSockets (0) | 2020.08.11 |
블럭 암호 공격 (0) | 2020.08.07 |
Feistel SPN 구조 (0) | 2020.08.05 |
블록 암호화와 운용방식 (0) | 2020.08.05 |
댓글 영역