// Personal Key Management System (PKMS) Simulation Program // by Byoungcheon Lee, Joongbu University // 2014. 9. 29 import java.util.Scanner; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.math.BigInteger; import java.nio.charset.Charset; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Security; import java.security.Signature; import java.security.SignatureException; import java.security.UnrecoverableKeyException; import java.security.cert.CRLException; import java.security.cert.CertPath; import java.security.cert.CertPathValidator; import java.security.cert.CertPathValidatorException; import java.security.cert.CertStore; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateFactory; import java.security.cert.CertificateNotYetValidException; import java.security.cert.CertificateParsingException; import java.security.cert.CollectionCertStoreParameters; import java.security.cert.PKIXCertPathValidatorResult; import java.security.cert.PKIXParameters; import java.security.cert.TrustAnchor; import java.security.cert.X509CRL; import java.security.cert.X509CRLEntry; import java.security.cert.X509Certificate; import java.security.cert.X509Extension; import java.security.spec.InvalidKeySpecException; import java.security.spec.X509EncodedKeySpec; import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.Date; import java.util.Formatter; import java.util.GregorianCalendar; import java.util.List; import java.util.Set; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.asn1.x509.CRLReason; import org.bouncycastle.asn1.x509.KeyUsage; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.crypto.util.PublicKeyFactory; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.pqc.math.linearalgebra.ByteUtils; import org.bouncycastle.x509.X509V2CRLGenerator; import org.bouncycastle.x509.X509V3CertificateGenerator; import org.bouncycastle.x509.extension.AuthorityKeyIdentifierStructure; // import org.bouncycastle.x509.extension.SubjectKeyIdentifierStructure; @SuppressWarnings("deprecation") public class PKMS { // ÆÄÀÏ ÀúÀå½Ã È®ÀåÀÚ Á¤¸® // *.der : ÀÎÁõ¼­ // *.crl : ÀÎÁõ¼­Ãë¼Ò¸ñ·Ï // *.key : °³ÀÎÅ°¸¦ Å°½ºÅä¾î¿¡ ÀúÀå // *.pkey : °ø°³Å°¸¦ ¹ÙÀÌÆ®½ºÆ®¸²À¸·Î ÆÄÀÏ¿¡ ÀúÀå // *.dsig : ±â±âÀÎÁõ¼­¸íÀ» ¹ÙÀÌÆ®½ºÆ®¸²À¸·Î ÆÄÀÏ¿¡ ÀúÀå // *.enc : ¾ÏÈ£¹®À» ¹ÙÀÌÆ®½ºÆ®¸²À¸·Î ÆÄÀÏ¿¡ ÀúÀå // *.sig : ¼­¸í¹®À» ¹ÙÀÌÆ®½ºÆ®¸²À¸·Î ÆÄÀÏ¿¡ ÀúÀå enum CertType {ROOT,INTER,ENDENTITY}; // ÀÎÁõ¼­ÀÇ Á¾·ù: ·çÆ®ÀÎÁõ±â°ü ÀÎÁõ¼­, Áß°£ ÀÎÁõ±â°ü ÀÎÁõ¼­, °³ÀÎÀÎÁõ¼­ // ÇÔ¼ö 3°³ ¼±¾ð // 1. RSA Å°»ý¼º ÇÔ¼ö - KeyPair¸¦ ¸®ÅÏ public static KeyPair generateRSAKeyPair() throws NoSuchAlgorithmException { KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); kpg.initialize(1024); return kpg.genKeyPair(); } // 2. ÀÎÁõ¼­ »ý¼º ÇÔ¼ö public static X509Certificate generateCertificate( X500Principal subjectDN, // ÁÖü PublicKey pubKey, // °ø°³Å° PrivateKey signatureKey, // ¹ß±ÞÅ° (¹ß±ÞÀÚÀÇ ¼­¸íÅ°) X509Certificate caCert, // ¹ß±ÞÀÚ ÀÎÁõ¼­ CertType type) // ÀÎÁõ¼­ Á¾·ù throws CertificateEncodingException,NoSuchProviderException,NoSuchAlgorithmException,SignatureException,InvalidKeyException,CertificateParsingException { X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.setSerialNumber(BigInteger.valueOf(System.currentTimeMillis())); // ÀÎÁõ¼­ ÀϷùøÈ£¸¦ ÇöÀç½Ã°£Á¤º¸·ÎºÎÅÍ ¼³Á¤ if(type==CertType.ROOT) // ·çÆ®ÀÎÁõ¼­ÀÎ °æ¿ì ¹ß±ÞÀÚ¿Í »ç¿ëÀÚ°¡ ¶È°°ÀÌ ·çÆ®ÀÓ certGen.setIssuerDN(subjectDN); else // ÀÏ¹Ý »ç¿ëÀÚ ÀÎÁõ¼­ÀÎ °æ¿ì ¹ß±ÞÀÚ´Â ÇÔ¼ö¿¡ ÀÔ·ÂµÈ °ªÀ» ÀÌ¿ë. caCert¿¡ ÀÖ´Â subjectDNÀ» ÀÌ¿ë certGen.setIssuerDN(caCert.getSubjectX500Principal()); certGen.setSubjectDN(subjectDN); // »ç¿ëÀÚ(ÁÖü)ÀÇ DNÀ» ¼³Á¤ GregorianCalendar currentDate = new GregorianCalendar(); // ¹ß±Þ½Ã°£Àº ÇöÀç ½Ã°£À¸·Î GregorianCalendar expiredDate // ¸¸·á½Ã°£, ÀÎÁõ¼­ÀÇ À¯È¿±â°£Àº 2³âÀ¸·Î ¼³Á¤ÇßÀ½ = new GregorianCalendar(currentDate.get(Calendar.YEAR)+2,currentDate.get(Calendar.MONTH),currentDate.get(Calendar.DAY_OF_MONTH)); certGen.setNotBefore(currentDate.getTime()); // À¯È¿±â°£ ½ÃÀÛ ¼³Á¤ certGen.setNotAfter(expiredDate.getTime()); // À¯È¿±â°£ ¸¸·á ¼³Á¤ certGen.setPublicKey(pubKey); // °ø°³Å° ¼³Á¤ certGen.setSignatureAlgorithm("SHA1withRSAEncryption"); // ¼­¸í¾Ë°í¸®Áò ¼³Á¤ if(type!=CertType.ROOT){ // ·çÆ®ÀÎÁõ¼­ÀÎ °æ¿ìÀÇ È®À念¿ª certGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(caCert)); // certGen.addExtension(X509Extensions.SubjectKeyIdentifier, false, // new SubjectKeyIdentifierStructure(pubKey)); } if(type!=CertType.ENDENTITY){ // Áß°£ ÀÎÁõ±â°üÀÎ °æ¿ìÀÇ È®À念¿ª. Å°ÀÇ »ç¿ë¿ëµµ¸¦ ÀüÀÚ¼­¸í, ÀÎÁõ¼­ ¼­¸í, CRL ¼­¸íÀÇ ¿ëµµ·Î »ç¿ëÇÒ ¼ö ÀÖÀ½ certGen.addExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(0)); certGen.addExtension(X509Extensions.KeyUsage, true, new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyCertSign | KeyUsage.cRLSign)); } else // ÀÏ¹Ý »ç¿ëÀÚÀÎ °æ¿ìÀÇ È®À念¿ª. Å°ÀÇ »ç¿ë¿ëµµ´Â ÀüÀÚ¼­¸í¿ë, Å°¾Ïȣȭ¿ëÀ¸·Î »ç¿ë °¡´É certGen.addExtension(X509Extensions.KeyUsage, true, new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyEncipherment)); return certGen.generate(signatureKey,"BC"); // ÀÎÁõ¼­¸¦ »ý¼ºÇÏ¿© °á°ú·Î ¸®ÅÏ } // 3. CRL »ý¼º ÇÔ¼ö. CRLÀº ÀÎÁõ±â°üÀÌ »ý¼ºÇÏ¿© °øÇ¥ public static X509CRL generateCRL( X509Certificate caCert, // CRL ¹ß±ÞÀÚ ÀÎÁõ¼­ PrivateKey signatureKey, // CRL ¹ß±ÞÀÚ ¼­¸íÅ° BigInteger serialNumber) // ÆóÁöÇÒ ÀÎÁõ¼­ ÀϷùøÈ£ throws CRLException,NoSuchProviderException,NoSuchAlgorithmException,SignatureException,InvalidKeyException{ X509V2CRLGenerator crlGen = new X509V2CRLGenerator(); // CRLÀ» À§ÇÑ º¯¼ö¸í ¼³Á¤ crlGen.setIssuerDN(caCert.getSubjectX500Principal()); // CRLÀÇ ¹ß±ÞÀÚ´Â ÀÎÁõ±â°ü GregorianCalendar currentDate = new GregorianCalendar(); // ¹ß±Þ½Ã°£ GregorianCalendar nextDate // ´ÙÀ½ ¾÷µ¥ÀÌÆ® ½Ã°£ = new GregorianCalendar(currentDate.get(Calendar.YEAR)+1,(currentDate.get(Calendar.MONTH)+1)%12,currentDate.get(Calendar.DAY_OF_MONTH)); crlGen.setThisUpdate(currentDate.getTime()); crlGen.setNextUpdate(nextDate.getTime()); crlGen.setSignatureAlgorithm("SHA1withRSAEncryption"); // ¼­¸í¾Ë°í¸®Áò ¼³Á¤ if(serialNumber!=null) // ÆóÁöÇÒ ÀÎÁõ¼­ÀÇ ÀϷùøÈ£¸¦ ¿£Æ®¸®¿¡ Ãß°¡ crlGen.addCRLEntry(serialNumber, currentDate.getTime(), CRLReason.superseded); return crlGen.generate(signatureKey,"BC"); // CRLÀ» »ý¼ºÇÏ¿© Ãâ·Â } // 4. RSA ¾Ïȣȭ ÇÔ¼ö, º¹È£È­ ÇÔ¼ö public static byte[] rsaEncrypt(byte[] plain, PublicKey pubk) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { Cipher c = Cipher.getInstance("RSA"); c.init(Cipher.ENCRYPT_MODE, pubk); byte[] cipher = c.doFinal(plain); return cipher; } public static byte[] rsaDecrypt(byte[] cipher, PrivateKey privk) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { Cipher c = Cipher.getInstance("RSA"); c.init(Cipher.DECRYPT_MODE, privk); byte[] plain = c.doFinal(cipher); return plain; } // 5. RSA ¼­¸í »ý¼º ÇÔ¼ö, ¼­¸í °ËÁõ ÇÔ¼ö public static byte[] rsaSign(byte[] plain, PrivateKey privk) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, SignatureException { Signature sig = Signature.getInstance("MD5WithRSA"); sig.initSign(privk); sig.update(plain); byte[] signatureBytes = sig.sign(); return signatureBytes; } public static boolean rsaVerify(byte[] plain, byte[] sign, PublicKey pubk) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, SignatureException { Signature sig = Signature.getInstance("MD5WithRSA"); sig.initVerify(pubk); sig.update(plain); return sig.verify(sign); } // 6. RSA ¼­¸í/°ËÁõ ÇÔ¼ö - ÀÔ·ÂÀÌ 2°³ÀÎ °æ¿ì , name: ±â±â¸í, key: °ø°³Å° public static byte[] rsaSign(byte[] name, byte[] key, PrivateKey privk) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, SignatureException { Signature sig = Signature.getInstance("MD5WithRSA"); sig.initSign(privk); sig.update(name); sig.update(key); byte[] signatureBytes = sig.sign(); return signatureBytes; } public static boolean rsaVerify(byte[] m1, byte[] m2, byte[] sign, PublicKey pubk) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, SignatureException { Signature sig = Signature.getInstance("MD5WithRSA"); sig.initVerify(pubk); sig.update(m1); sig.update(m2); return sig.verify(sign); } public static String bytesToHex(byte[] bytes) { StringBuilder sb = new StringBuilder(bytes.length * 2); @SuppressWarnings("resource") Formatter formatter = new Formatter(sb); for (byte b : bytes) { formatter.format("%02x", b); } return sb.toString(); } // ¸Þ´º 1. ÀÎÁõ±â°ü ¼³Á¤ ÇÔ¼ö - Å°»ý¼º, ÀÎÁõ¼­ »ý¼º, ÀúÀå public static void InitializeCA() throws IOException { try{ // 1.1 Å°½Ö»ý¼º System.out.println(); System.out.println("1. ÀÎÁõ±â°ü ¼³Á¤ (ÀÎÁõ±â°ü ³»ºÎÀÇ ÀÛ¾÷) "); System.out.println("1.1 Å°½Ö »ý¼º "); KeyPair rootKeyPair = generateRSAKeyPair(); // ·çÆ®ÀÎÁõ±â°ü Å°»ý¼º ¹× ÀÎÁõ¼­ ¹ß±Þ KeyPair interKeyPair = generateRSAKeyPair(); // Áß°£ÀÎÁõ±â°üÀÇ Å°»ý¼º ¹× ÀÎÁõ¼­ ¹ß±Þ // 1.2 ÀÎÁõ¼­ »ý¼º System.out.println("1.2 ÀÎÁõ¼­ »ý¼º "); X509Certificate rootCert = generateCertificate( new X500Principal("C=KR,CN=ROOT"), rootKeyPair.getPublic(), rootKeyPair.getPrivate(), null, CertType.ROOT); X509Certificate interCert = generateCertificate( new X500Principal("C=KR,CN=INTER"), interKeyPair.getPublic(), rootKeyPair.getPrivate(), rootCert, CertType.INTER); // 1.3 ÀÎÁõ¼­Ãë¼Ò¸ñ·Ï(CRL) »ý¼º System.out.println("1.3 ÀÎÁõ¼­Ãë¼Ò¸ñ·Ï(CRL) »ý¼º "); X509CRL rootCRL = generateCRL(rootCert,rootKeyPair.getPrivate(),null); X509CRL interCRL = generateCRL(interCert,interKeyPair.getPrivate(),null); // 1.4 ÀÎÁõ¼­¸¦ ÆÄÀÏ·Î ÀúÀå System.out.println("1.4 ÀÎÁõ¼­¸¦ *.der ÆÄÀÏ·Î ÀúÀå "); FileOutputStream fos; fos = new FileOutputStream(new File("root.der")); fos.write(rootCert.getEncoded()); // ÆÄÀÏ·Î ÀúÀå fos.close(); fos = new FileOutputStream(new File("inter.der")); fos.write(interCert.getEncoded()); // ÆÄÀÏ·Î ÀúÀå fos.close(); // 1.5 °³ÀÎÅ°¸¦ ÆÄÀÏ·Î ÀúÀå System.out.println("1.5 °³ÀÎÅ°¸¦ *.key ÆÄÀÏ·Î ÀúÀå "); char[] code = {'s','e','c','r','e','t','c','o','d','e'}; // °³ÀÎÅ° ¾Ïȣȭ¸¦ À§ÇÑ Å° ÄÚµå ¼³Á¤. ÆíÀÇ»ó °íÁ¤ÇÏ¿´À½ // ÀÌ ¼ÒÇÁÆ®¿þ¾î¸¦ ¿©·¯ »ç¿ëÀÚ°¡ »ç¿ëÇÏ°Ô µÇ´Â °æ¿ì Å° Äڵ带 »ç¿ëÀÚ ÀÔ·ÂÀ¸·Î ¹ÞÀ» ¼ö ÀÖµµ·Ï º¯°æÇÒ ÇÊ¿ä // Áß°£ÀÎÁõ±â°üÀÇ °³ÀÎÅ°¸¦ ÀúÀå KeyStore ks1 = KeyStore.getInstance(KeyStore.getDefaultType()); // Å°½ºÅä¾î¶ó´Â ÇüÅ·ΠÀúÀåÇÏ°Ô µÊ ks1.load(null,null); X509Certificate[] chain1 = new X509Certificate[2]; // Å°½ºÅä¾î¿¡ ÀúÀå½Ã ÀÎÁõüÀÎ Á¤º¸ ÇÊ¿ä. ·çÆ®·ÎºÎÅÍ »ç¿ëÀÚ±îÁöÀÇ ÀÎÁõ¼­ Á¤º¸ chain1[0] = interCert; // Áß°£ÀÎÁõ±â°ü ÀÎÁõ¼­ (Áß°£ÀÎÁõ±â°üÀÌ Alice¿¡°Ô ÀÎÁõ¼­¸¦ ¹ß±Þ) chain1[1] = rootCert; // ·çÆ®ÀÎÁõ±â°ü ÀÎÁõ¼­ (·çÆ®ÀÎÁõ±â°üÀÌ Áß°£ÀÎÁõ±â°ü¿¡°Ô ÀÎÁõ¼­¸¦ ¹ß±Þ) ks1.setKeyEntry("InterPrivateKeyAlias",interKeyPair.getPrivate(),code,chain1); // ÇÊ¿äÇÑ Á¤º¸¸¦ Å°½ºÅä¾î¿¡ ¾ÏȣȭÇÏ¿© ÀúÀå fos = new FileOutputStream(new File("inter.key")); ks1.store(fos,code); // Å°½ºÅä¾îÀÇ ³»¿ëÀ» code·Î ¾ÏȣȭÇÏ¿© ÆÄÀÏ·Î ÀúÀå fos.close(); // ·çÆ®ÀÎÁõ±â°üÀÇ °³ÀÎÅ°¸¦ ÀúÀå KeyStore ks2 = KeyStore.getInstance(KeyStore.getDefaultType()); // Å°½ºÅä¾î¶ó´Â ÇüÅ·ΠÀúÀåÇÏ°Ô µÊ ks2.load(null,null); X509Certificate[] chain2 = new X509Certificate[1]; // Å°½ºÅä¾î¿¡ ÀúÀå½Ã ÀÎÁõüÀÎ Á¤º¸ ÇÊ¿ä. ·çÆ®·ÎºÎÅÍ »ç¿ëÀÚ±îÁöÀÇ ÀÎÁõ¼­ Á¤º¸ chain2[0] = rootCert; // ·çÆ®ÀÎÁõ±â°ü ÀÎÁõ¼­ (·çÆ®ÀÎÁõ±â°üÀÌ Áß°£ÀÎÁõ±â°ü¿¡°Ô ÀÎÁõ¼­¸¦ ¹ß±Þ) ks2.setKeyEntry("RootPrivateKeyAlias",rootKeyPair.getPrivate(),code,chain2); // ÇÊ¿äÇÑ Á¤º¸¸¦ Å°½ºÅä¾î¿¡ ¾ÏȣȭÇÏ¿© ÀúÀå fos = new FileOutputStream(new File("root.key")); ks2.store(fos,code); // Å°½ºÅä¾îÀÇ ³»¿ëÀ» code·Î ¾ÏȣȭÇÏ¿© ÆÄÀÏ·Î ÀúÀå fos.close(); // 1.6 CRLÀ» ÆÄÀÏ·Î ÀúÀå - ´çÀå ¾µ ÀÏÀº ¾øÀ½ System.out.println("1.6 CRLÀ» *.crl ÆÄÀÏ·Î ÀúÀå "); // Áß°£ÀÎÁõ±â°üÀÇ CRL fos = new FileOutputStream(new File("inter.crl")); fos.write(interCRL.getEncoded()); fos.close(); // ·çÆ®ÀÎÁõ±â°üÀÇ CRL fos = new FileOutputStream(new File("root.crl")); fos.write(rootCRL.getEncoded()); fos.close(); System.out.println(); } catch(NoSuchAlgorithmException nsae){ nsae.printStackTrace(); } catch(CertificateException ce){ ce.printStackTrace(); } catch(InvalidKeyException ike){ ike.printStackTrace(); } catch(SignatureException se){ se.printStackTrace(); } catch(NoSuchProviderException nspre){ nspre.printStackTrace(); } catch(KeyStoreException kse){ kse.printStackTrace(); } catch(CRLException nsae){ nsae.printStackTrace(); } } // ¸Þ´º 2. »ç¿ëÀÚ¿¡°Ô ÀÎÁõ¼­ ¹ß±ÞÇÏ´Â ÇÔ¼ö - »ç¿ëÀÚ°¡ ÀÎÁõ¼­ ¹ß±Þ ¿äû, ÀÎÁõ±â°üÀÌ ÀÎÁõ¼­ ¹ß±Þ public static void IssueCert(String userName) throws IOException, UnrecoverableKeyException, InvalidKeySpecException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException { try{ byte[] m1, m2, s0, s1; System.out.println(); System.out.println("2. »ç¿ëÀÚ¿¡°Ô ÀÎÁõ¼­ ¹ß±Þ "); // 2.1 »ç¿ëÀÚ Å°½Ö»ý¼º (»ç¿ëÀÚ) System.out.println("2.1 Å°½Ö »ý¼º (»ç¿ëÀÚ) "); KeyPair userKeyPair = generateRSAKeyPair(); // »ç¿ëÀÚÀÇ Å°½Ö »ý¼º // 2.2 ÀÎÁõ¼­ ¹ß±Þ ¿äû (»ç¿ëÀÚ) // - °ø°³Å°¸¦ ¹ÙÀÌÆ®½ºÆ®¸²À¸·Î ÆÄÀÏ¿¡ ÀúÀå (»ç¿ëÀÚ) FileInputStream fis; FileOutputStream fos; fos = new FileOutputStream(new File(userName+".pkey")); fos.write(userKeyPair.getPublic().getEncoded()); fos.close(); // °³ÀÎÅ° ¼ÒÀ¯ Áõ¸íÀ» À§ÇØ ¼­¸íÀ» ÀÛ¼º m1 = userName.getBytes(); // »ç¿ëÀÚ¸í m2 = userKeyPair.getPublic().getEncoded(); // ±â±âÀÇ °ø°³Å° s0 = rsaSign(m1, m2, userKeyPair.getPrivate()); // µÎ°³ÀÇ ¸Þ½ÃÁö m1, m2¿¡ ´ëÇØ °³ÀÎÅ°·Î ¼­¸í. fos = new FileOutputStream(new File(userName+".rsig")); // ÀÎÁõ¼­¹ß±Þ¿äû¼­¸íÀ» ÆÄÀÏ·Î ÀúÀå fos.write(s0); fos.close(); // - °ø°³Å°, ÀÎÁõ¼­¹ß±Þ¿äû¼­¸íÀ» ÀÎÁõ±â°ü¿¡°Ô Àü¼Û System.out.println("2.2 ÀÎÁõ¼­ ¹ß±Þ ¿äû (»ç¿ëÀÚ->ÀÎÁõ±â°ü) "); // 2.3 ÀÎÁõ¼­ ¹ß±Þ (ÀÎÁõ±â°ü) // Áß°£ÀÎÁõ±â°üÀÇ ÀÎÁõ¼­ Àоî¿À±â CertificateFactory cf = CertificateFactory.getInstance("X.509"); fis = new FileInputStream(new File("inter.der")); X509Certificate interCert = (X509Certificate)cf.generateCertificate(fis); // ÆÄÀÏ¿¡¼­ Àо ÀÎÁõ¼­ Çü½ÄÀ¸·Î ÇÒ´ç fis.close(); fis = new FileInputStream(new File("root.der")); X509Certificate rootCert = (X509Certificate)cf.generateCertificate(fis); // ÆÄÀÏ¿¡¼­ Àо ÀÎÁõ¼­ Çü½ÄÀ¸·Î ÇÒ´ç fis.close(); // Áß°£ÀÎÁõ±â°üÀÇ °³ÀÎÅ° Àоî¿À±â KeyStore ks; char[] code = {'s','e','c','r','e','t','c','o','d','e'}; // °³ÀÎÅ° ¾Ïȣȭ¸¦ À§ÇÑ Å° ÄÚµå ¼³Á¤. ÆíÀÇ»ó °íÁ¤ÇÏ¿´À½ fis = new FileInputStream(new File("inter.key")); ks = KeyStore.getInstance(KeyStore.getDefaultType()); ks.load(fis,code); // ÆÄÀÏ¿¡¼­ Àоî¿Í¼­ Å°½ºÅä¾î¿¡ ·Îµå fis.close(); PrivateKey interPrivateKey = (PrivateKey)ks.getKey("InterPrivateKeyAlias",code); // »ç¿ëÀÚÀÇ °ø°³Å°¸¦ ÆÄÀÏ¿¡¼­ Àоî¿À±â fis = new FileInputStream(new File(userName+".pkey")); int size = fis.available(); byte[] s = new byte[size]; fis.read(s); fis.close(); X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(s); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PublicKey userPublicKey = keyFactory.generatePublic(pubKeySpec); // ÀÎÁõ¼­¹ß±Þ¿äû¼­¸íÀ» °ËÁõ fis = new FileInputStream(new File(userName+".rsig")); size = fis.available(); s1 = new byte[size]; fis.read(s1); fis.close(); boolean result = rsaVerify(m1,m2,s1,userPublicKey); System.out.println(" - ÀÎÁõ¼­¹ß±Þ¿äû¼­¸íÀÇ À¯È¿¼º °ËÁõ (ÀÎÁõ±â°ü) : "+result); // ÀÎÁõ¼­ »ý¼ºÇϱâ X509Certificate userCert = generateCertificate( new X500Principal("C=KR,CN="+userName), userPublicKey, interPrivateKey, interCert, CertType.ENDENTITY); // ÀÎÁõ¼­¸¦ ÆÄÀÏ·Î ÀúÀåÇϱâ fos = new FileOutputStream(new File(userName+".der")); fos.write(userCert.getEncoded()); // ÆÄÀÏ·Î ÀúÀå fos.close(); // ÀÎÁõ¼­¸¦ »ç¿ëÀÚ¿¡°Ô Àü¼Û. ÀÎÁõ±â°ü ÀÎÁõ¼­µµ ÇÔ²² Àü¼Û System.out.println("2.3 ÀÎÁõ¼­¸¦ »ç¿ëÀÚ¿¡°Ô Àü¼Û (ÀÎÁõ±â°ü->»ç¿ëÀÚ) "); // 2.4 °³ÀÎÅ°¸¦ ÆÄÀÏ·Î ÀúÀå (»ç¿ëÀÚ) System.out.println("2.4 °³ÀÎÅ°¸¦ *.key ÆÄÀÏ·Î ÀúÀå (»ç¿ëÀÚ) "); // ÀÎÁõ±â°üÀÇ ÀÎÁõ¼­ Àоî¿À±â (»ç¿ëÀÚ °³ÀÎÅ° ÀúÀå¿¡ ÀÎÁõ¼­ üÀÎÀÌ ÇÊ¿ä) // System.out.println("\n* 1.2 ÀÎÁõ¼­ Àоî¿À±â "); fis = new FileInputStream(new File("inter.der")); interCert = (X509Certificate)cf.generateCertificate(fis); // ÆÄÀÏ¿¡¼­ Àо ÀÎÁõ¼­ Çü½ÄÀ¸·Î ÇÒ´ç fis.close(); fis = new FileInputStream(new File("root.der")); rootCert = (X509Certificate)cf.generateCertificate(fis); // ÆÄÀÏ¿¡¼­ Àо ÀÎÁõ¼­ Çü½ÄÀ¸·Î ÇÒ´ç fis.close(); // »ç¿ëÀÚÀÇ °³ÀÎÅ°¸¦ ÀúÀå KeyStore ks1 = KeyStore.getInstance(KeyStore.getDefaultType()); // Å°½ºÅä¾î¶ó´Â ÇüÅ·ΠÀúÀåÇÏ°Ô µÊ ks1.load(null,null); X509Certificate[] chain1 = new X509Certificate[3]; // Å°½ºÅä¾î¿¡ ÀúÀå½Ã ÀÎÁõüÀÎ Á¤º¸ ÇÊ¿ä. ·çÆ®·ÎºÎÅÍ »ç¿ëÀÚ±îÁöÀÇ ÀÎÁõ¼­ Á¤º¸ chain1[0] = userCert; // »ç¿ëÀÚ ÀÎÁõ¼­ (Áß°£ÀÎÁõ±â°üÀÌ Alice¿¡°Ô ÀÎÁõ¼­¸¦ ¹ß±Þ) chain1[1] = interCert; // Áß°£ÀÎÁõ±â°ü ÀÎÁõ¼­ (Áß°£ÀÎÁõ±â°üÀÌ Alice¿¡°Ô ÀÎÁõ¼­¸¦ ¹ß±Þ) chain1[2] = rootCert; // ·çÆ®ÀÎÁõ±â°ü ÀÎÁõ¼­ (·çÆ®ÀÎÁõ±â°üÀÌ Áß°£ÀÎÁõ±â°ü¿¡°Ô ÀÎÁõ¼­¸¦ ¹ß±Þ) ks1.setKeyEntry(userName+"PrivateKeyAlias",userKeyPair.getPrivate(),code,chain1); // ÇÊ¿äÇÑ Á¤º¸¸¦ Å°½ºÅä¾î¿¡ ¾ÏȣȭÇÏ¿© ÀúÀå fos = new FileOutputStream(new File(userName+".key")); ks1.store(fos,code); // Å°½ºÅä¾îÀÇ ³»¿ëÀ» code·Î ¾ÏȣȭÇÏ¿© ÆÄÀÏ·Î ÀúÀå fos.close(); // 2.5 ¹ß±Þ¹ÞÀº ÀÎÁõ¼­ÀÇ À¯È¿¼º °ËÁõ (»ç¿ëÀÚ) // »ç¿ëÀÚ ÀÎÁõ¼­ Àоî¿À±â fis = new FileInputStream(new File(userName+".der")); X509Certificate userCert1 = (X509Certificate)cf.generateCertificate(fis); // ÆÄÀÏ¿¡¼­ Àо ÀÎÁõ¼­ Çü½ÄÀ¸·Î ÇÒ´ç fis.close(); fis = new FileInputStream(new File("inter.der")); interCert = (X509Certificate)cf.generateCertificate(fis); // ÆÄÀÏ¿¡¼­ Àо ÀÎÁõ¼­ Çü½ÄÀ¸·Î ÇÒ´ç fis.close(); // ÀÎÁõ¼­ÀÇ À¯È¿¼º °ËÁõ userCert1.checkValidity(); userCert1.verify(interCert.getPublicKey()); // »ç¿ëÀÚ ÀÎÁõ¼­ÀÇ À¯È¿¼º °ËÁõ System.out.println("2.5 »ç¿ëÀÚ ÀÎÁõ¼­ÀÇ À¯È¿¼º °ËÁõ (»ç¿ëÀÚ) "); System.out.println(); } catch(NoSuchAlgorithmException nsae){ nsae.printStackTrace(); } catch(CertificateException ce){ ce.printStackTrace(); } catch(InvalidKeyException ike){ ike.printStackTrace(); } catch(SignatureException se){ se.printStackTrace(); } catch(NoSuchProviderException nspre){ nspre.printStackTrace(); } catch(KeyStoreException kse){ kse.printStackTrace(); } } // ¸Þ´º 3. »ç¿ëÀÚÀÇ ±â±â¸¦ µî·ÏÇÏ´Â ÇÔ¼ö - ±â±âÀÎÁõ¼­¸í ¹ß±Þ public static void SetupDevice(String userName, String machineName) throws IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, SignatureException, InvalidKeySpecException { // PKMS (»ç¿ëÀÚ Å°°ü¸®¼­¹ö), UD (»ç¿ëÀÚ ±â±â) °£ÀÇ ÇÁ·ÎÅäÄÝ KeyPair machineKeyPair; // »ç¿ëÀÚ ±â±â¿¡¼­ »ç¿ëÇÒ Å°½Ö FileInputStream fis; FileOutputStream fos; KeyStore ks; byte[] m1; // »ç¿ëÀÚ¸í+±â±â¸í ¹ÙÀÌÆ®½ºÆ®¸² byte[] m2; // ±â±âÀÇ °ø°³Å° ¹ÙÀÌÆ®½ºÆ®¸² byte[] s0; // ±â±âÀÎÁõ¼­¸í byte[] s1=null; // ±â±âÀÎÁõ¼­¸í (ÆÄÀÏ¿¡¼­ Àоî¿Â °Í) boolean result; // ±â±âÀÎÁõ¼­¸í °ËÁõ °á°ú int size; // ÆÄÀÏ¿¡¼­ ¹ÙÀÌÆ®½ºÆ®¸² Àоî¿Ã¶§ Å©±â char[] code = {'s','e','c','r','e','t','c','o','d','e'}; // °³ÀÎÅ° ¾Ïȣȭ¸¦ À§ÇÑ Å° ÄÚµå ¼³Á¤. ÆíÀÇ»ó °íÁ¤ÇÏ¿´À½ // 3.1 ±â±â¿¡¼­ »ç¿ëÇÒ Å°½Ö »ý¼º (UD) machineKeyPair = generateRSAKeyPair(); // »õ·Î¿î Å°»ý¼º System.out.println("3.1 ±â±â Å°½Ö »ý¼º "); // 3.2 ±â±âÀÎÁõ¼­¸í ¹ß±Þ ¿äû (UD->PKMS) // ±â±â°ø°³Å°¸¦ ÆÄÀÏ·Î ÀúÀå (UD) fos = new FileOutputStream(new File(userName+machineName+".pkey")); fos.write(machineKeyPair.getPublic().getEncoded()); fos.close(); System.out.println("3.2 ±â±âÀÎÁõ¼­¸í ¹ß±Þ ¿äû "); // ±â±â°ø°³Å°¸¦ PKMS¿¡°Ô Àü¼Û, ±â±âÀÎÁõ¼­¸í ¹ß±Þ¿äû (UD) // 3.3 ±â±âÀÎÁõ¼­¸í ¹ß±Þ (PKMS->UD) // PKMSÀÇ ÀÎÁõ¼­ Àоî¿À±â (PKMS) CertificateFactory cf = CertificateFactory.getInstance("X.509"); fis = new FileInputStream(new File(userName+".der")); X509Certificate userCert = (X509Certificate)cf.generateCertificate(fis); // ÆÄÀÏ¿¡¼­ Àо ÀÎÁõ¼­ Çü½ÄÀ¸·Î ÇÒ´ç fis.close(); // PKMSÀÇ °³ÀÎÅ° Àоî¿À±â (PKMS) fis = new FileInputStream(new File(userName+".key")); ks = KeyStore.getInstance(KeyStore.getDefaultType()); ks.load(fis,code); // ÆÄÀÏ¿¡¼­ Àоî¿Í¼­ Å°½ºÅä¾î¿¡ ·Îµå fis.close(); PrivateKey userPrivateKey = (PrivateKey)ks.getKey(userName+"PrivateKeyAlias",code); // »ç¿ëÀÚ ±â±âÀÇ °ø°³Å°¸¦ ÆÄÀÏ¿¡¼­ Àоî¿À±â (PKMS) fis = new FileInputStream(new File(userName+machineName+".pkey")); size = fis.available(); byte[] s = new byte[size]; fis.read(s); fis.close(); X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(s); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PublicKey machinePublicKey = keyFactory.generatePublic(pubKeySpec); // ±â±âÀÎÁõ¼­¸í »ý¼º (PKMS) m1 = (userName+machineName).getBytes(); // »ç¿ëÀÚ¸í+±â±â¸í ÇÔ²² »ç¿ë m2 = machineKeyPair.getPublic().getEncoded(); // ±â±âÀÇ °ø°³Å° s0 = rsaSign(m1, m2, userPrivateKey); // µÎ°³ÀÇ ¸Þ½ÃÁö m1, m2¿¡ ´ëÇØ ÀÎÁõÅ°·Î ¼­¸í. fos = new FileOutputStream(new File(userName+machineName+".dsig")); // ±â±âÀÎÁõ¼­¸íÀ» ÆÄÀÏ·Î ÀúÀå fos.write(s0); fos.close(); // ±â±âÀÎÁõ¼­¸íÀ» UD¿¡°Ô Àü¼Û (PKMS->UD) // »ç¿ëÀÚ ÀÎÁõ¼­, ÀÎÁõ±â°ü ÀÎÁõ¼­¸¦ ÇÔ²² Àü¼Û System.out.println("3.3 ±â±âÀÎÁõ¼­¸í ¹ß±Þ "); // 3.4 ±â±âÀÎÁõ¼­¸íÀÇ À¯È¿¼º °ËÁõ (UD) // ±â±âÀÎÁõ¼­¸í Àоî¿À±â (UD) fis = new FileInputStream(new File(userName+machineName+".dsig")); size = fis.available(); s1 = new byte[size]; fis.read(s1); fis.close(); m1 = (userName+machineName).getBytes(); m2 = machinePublicKey.getEncoded(); result = rsaVerify(m1,m2,s1,userCert.getPublicKey()); System.out.println("3.4 "+machineName+"ÀÇ ±â±âÀÎÁõ¼­¸í À¯È¿¼º °ËÁõ : "+result); // 3.5 ±â±â °³ÀÎÅ°¸¦ Å°½ºÅä¾î¿¡ ÀúÀå // ÀÎÁõ±â°üÀÇ ÀÎÁõ¼­ Àоî¿À±â fis = new FileInputStream(new File("inter.der")); X509Certificate interCert = (X509Certificate)cf.generateCertificate(fis); // ÆÄÀÏ¿¡¼­ Àо ÀÎÁõ¼­ Çü½ÄÀ¸·Î ÇÒ´ç fis.close(); fis = new FileInputStream(new File("root.der")); X509Certificate rootCert = (X509Certificate)cf.generateCertificate(fis); // ÆÄÀÏ¿¡¼­ Àо ÀÎÁõ¼­ Çü½ÄÀ¸·Î ÇÒ´ç fis.close(); // ±â±â °³ÀÎÅ°¸¦ Å°½ºÅä¾î¿¡ ÀúÀå X509Certificate[] chain = new X509Certificate[3]; // Å°½ºÅä¾î¿¡ ÀúÀå½Ã ÀÎÁõüÀÎ Á¤º¸ ÇÊ¿ä. ·çÆ®·ÎºÎÅÍ »ç¿ëÀÚ±îÁöÀÇ ÀÎÁõ¼­ Á¤º¸ chain[0] = userCert; // »ç¿ëÀÚ ÀÎÁõ¼­ chain[1] = interCert; // Áß°£ÀÎÁõ±â°ü ÀÎÁõ¼­ chain[2] = rootCert; // ·çÆ®ÀÎÁõ±â°ü ÀÎÁõ¼­ ks = KeyStore.getInstance(KeyStore.getDefaultType()); // Å°½ºÅä¾î¶ó´Â ÇüÅ·ΠÀúÀåÇÏ°Ô µÊ ks.load(null,null); ks.setKeyEntry(userName+machineName+"PrivateKeyAlias",machineKeyPair.getPrivate(),code,chain); // ÇÊ¿äÇÑ Á¤º¸¸¦ Å°½ºÅä¾î¿¡ ¾ÏȣȭÇÏ¿© ÀúÀå fos = new FileOutputStream(new File(userName+machineName+".key")); ks.store(fos,code); // Å°½ºÅä¾îÀÇ ³»¿ëÀ» code·Î ¾ÏȣȭÇÏ¿© ÆÄÀÏ·Î ÀúÀå fos.close(); System.out.println("3.5 ±â±â °³ÀÎÅ°¸¦ Å°½ºÅä¾î¿¡ ÀúÀå "); System.out.println(); } // ¸Þ´º 4. »ç¿ëÀÚÀÇ ±â±â »çÀÌÀÇ ¾Ïȣȭ/º¹È£È­ Å×½ºÆ® // ¼Û½ÅÀÚ ±â±â (SUD), ¼ö½ÅÀÚ ±â±â (RUD) °£ÀÇ ÇÁ·ÎÅäÄÝ // ¼Û½ÅÀÚ ±â±â´Â ¼ö½ÅÀÚ ±â±âÀÇ °ø°³Å°·Î ¾ÏȣȭÇÏ¿© ¸Þ½ÃÁö Àü¼Û public static void TestEncryption(String receiverName, String machineName) throws IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, SignatureException, NoSuchProviderException, InvalidKeySpecException { FileInputStream fis; FileOutputStream fos; KeyStore ks; byte[] m1; // »ç¿ëÀÚ¸í+±â±â¸í ¹ÙÀÌÆ®½ºÆ®¸² byte[] m2; // ±â±âÀÇ °ø°³Å° ¹ÙÀÌÆ®½ºÆ®¸² byte[] s0; // ±â±âÀÎÁõ¼­¸í byte[] s1=null; // ±â±âÀÎÁõ¼­¸í (ÆÄÀÏ¿¡¼­ Àоî¿Â °Í) boolean result; // ±â±âÀÎÁõ¼­¸í °ËÁõ °á°ú int size; // ÆÄÀÏ¿¡¼­ ¹ÙÀÌÆ®½ºÆ®¸² Àоî¿Ã¶§ Å©±â char[] code = {'s','e','c','r','e','t','c','o','d','e'}; // °³ÀÎÅ° ¾Ïȣȭ¸¦ À§ÇÑ Å° ÄÚµå ¼³Á¤. ÆíÀÇ»ó °íÁ¤ÇÏ¿´À½ // 4.1 ¼ö½ÅÀÚÀÇ ÀÎÁõ¼­ Àоî¿Í¼­ °ËÁõÇϱâ (SUD) // ¼ö½ÅÀÚ PKMSÀÇ ÀÎÁõ¼­ Àоî¿À±â (SUD) CertificateFactory cf = CertificateFactory.getInstance("X.509"); fis = new FileInputStream(new File(receiverName+".der")); X509Certificate receiverCert = (X509Certificate)cf.generateCertificate(fis); // ÆÄÀÏ¿¡¼­ Àо ÀÎÁõ¼­ Çü½ÄÀ¸·Î ÇÒ´ç fis.close(); // ÀÎÁõ±â°üÀÇ ÀÎÁõ¼­ Àоî¿À±â fis = new FileInputStream(new File("inter.der")); X509Certificate interCert = (X509Certificate)cf.generateCertificate(fis); // ÆÄÀÏ¿¡¼­ Àо ÀÎÁõ¼­ Çü½ÄÀ¸·Î ÇÒ´ç fis.close(); // ÀÎÁõ¼­ÀÇ À¯È¿¼º °ËÁõ receiverCert.checkValidity(); receiverCert.verify(interCert.getPublicKey()); // »ç¿ëÀÚ ÀÎÁõ¼­ÀÇ À¯È¿¼º °ËÁõ System.out.println("4.1 ¼ö½ÅÀÚ ÀÎÁõ¼­ÀÇ À¯È¿¼º °ËÁõ : "); // 4.2 ¼ö½ÅÀÚ ±â±âÀÇ ±â±âÀÎÁõ¼­¸í °ËÁõ // ¼ö½ÅÀÚÀÇ ±â±âÀÎÁõ¼­¸í Àоî¿À±â (SUD) fis = new FileInputStream(new File(receiverName+machineName+".dsig")); size = fis.available(); s1 = new byte[size]; fis.read(s1); fis.close(); // ¼ö½ÅÀÚ ±â±âÀÇ °ø°³Å°¸¦ ÆÄÀÏ¿¡¼­ Àоî¿À±â (SUD) fis = new FileInputStream(new File(receiverName+machineName+".pkey")); size = fis.available(); byte[] s = new byte[size]; fis.read(s); fis.close(); X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(s); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PublicKey machinePublicKey = keyFactory.generatePublic(pubKeySpec); // ¼ö½ÅÀÚÀÇ ±â±âÀÎÁõ¼­¸í °ËÁõ (SUD) m1 = (receiverName+machineName).getBytes(); m2 = machinePublicKey.getEncoded(); result = rsaVerify(m1,m2,s1,receiverCert.getPublicKey()); System.out.println("4.2 "+receiverName+machineName+"ÀÇ ±â±âÀÎÁõ¼­¸í À¯È¿¼º °ËÁõ : "+result); // 4.3 ¾ÏÈ£¹® Àü¼ÛÇϱâ (SUD->RUD) String plaintext = "¾Ïȣȭ Å×½ºÆ®"; Charset charset = Charset.forName("UTF-8"); byte[] ct; // ¾ÏÈ£¹® ct = rsaEncrypt(plaintext.getBytes(charset), machinePublicKey); // ¾ÏÈ£¹®À» ÆÄÀÏ·Î ÀúÀå fos = new FileOutputStream(new File(receiverName+machineName+".enc")); // ¾ÏÈ£¹®À» ÆÄÀÏ·Î ÀúÀå fos.write(ct); fos.close(); // ¾ÏÈ£¹®À» ¼ö½ÅÀÚ¿¡°Ô Àü¼Û (SUD->RUD) System.out.println("4.3 ¾ÏÈ£¹® Àü¼Û ¿Ï·á "); System.out.println("¸Þ½ÃÁö : "+plaintext); System.out.println("¾ÏÈ£¹® : "+ByteUtils.toHexString(ct)); // 4.4 ¾ÏÈ£¹® º¹È£È­Çϱâ (RUD) // ¾ÏÈ£¹®À» ÆÄÀÏ¿¡¼­ Àоî¿È fis = new FileInputStream(new File(receiverName+machineName+".enc")); size = fis.available(); byte[] ct1 = new byte[size]; fis.read(ct1); fis.close(); // ¼ö½ÅÀÚ ±â±âÀÇ °³ÀÎÅ° Àоî¿À±â. fis = new FileInputStream(new File(receiverName+machineName+".key")); ks = KeyStore.getInstance(KeyStore.getDefaultType()); ks.load(fis,code); // ÆÄÀÏ¿¡¼­ Àоî¿Í¼­ Å°½ºÅä¾î¿¡ ·Îµå fis.close(); PrivateKey machinePrivateKey = (PrivateKey)ks.getKey(receiverName+machineName+"PrivateKeyAlias",code); // Å°½ºÅä¾î¿¡¼­ °³ÀÎÅ°¸¦ Àоî¿Ã¶§ ¾Ïȣȭ Å° ÄÚµå ÇÊ¿ä byte[] pt1 = rsaDecrypt(ct1,machinePrivateKey); String decryptedText = new String(pt1, charset); System.out.println("º¹È£È­ : "+decryptedText); System.out.println(); } // ¸Þ´º 5. »ç¿ëÀÚÀÇ ±â±â »çÀÌÀÇ ¼­¸í/°ËÁõ Å×½ºÆ® // ¼Û½ÅÀÚ ±â±â (SUD), ¼ö½ÅÀÚ ±â±â (RUD) °£ÀÇ ÇÁ·ÎÅäÄÝ // ¼Û½ÅÀÚ ±â±â´Â ÀÚ½ÅÀÇ ±â±âÀÇ °³ÀÎÅ°·Î ¼­¸íÇÏ¿© ¸Þ½ÃÁö Àü¼Û, ¼ö½ÅÀÚ ±â±â´Â ¼Û½ÅÀÚ ±â±âÀÇ °ø°³Å°·Î ¼­¸í °ËÁõ public static void TestSignature(String senderName, String machineName) throws IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, SignatureException, NoSuchProviderException, InvalidKeySpecException { FileInputStream fis; FileOutputStream fos; KeyStore ks; byte[] m1; // »ç¿ëÀÚ¸í+±â±â¸í ¹ÙÀÌÆ®½ºÆ®¸² byte[] m2; // ±â±âÀÇ °ø°³Å° ¹ÙÀÌÆ®½ºÆ®¸² byte[] s0; // ±â±âÀÎÁõ¼­¸í byte[] s1=null; // ±â±âÀÎÁõ¼­¸í (ÆÄÀÏ¿¡¼­ Àоî¿Â °Í) boolean result; // ±â±âÀÎÁõ¼­¸í °ËÁõ °á°ú int size; // ÆÄÀÏ¿¡¼­ ¹ÙÀÌÆ®½ºÆ®¸² Àоî¿Ã¶§ Å©±â char[] code = {'s','e','c','r','e','t','c','o','d','e'}; // °³ÀÎÅ° ¾Ïȣȭ¸¦ À§ÇÑ Å° ÄÚµå ¼³Á¤. ÆíÀÇ»ó °íÁ¤ÇÏ¿´À½ // 5.1 ¼Û½ÅÀÚÀÇ °³ÀÎÅ° Àоî¿À±â (SUD) fis = new FileInputStream(new File(senderName+machineName+".key")); ks = KeyStore.getInstance(KeyStore.getDefaultType()); ks.load(fis,code); // ÆÄÀÏ¿¡¼­ Àоî¿Í¼­ Å°½ºÅä¾î¿¡ ·Îµå fis.close(); PrivateKey machinePrivateKey = (PrivateKey)ks.getKey(senderName+machineName+"PrivateKeyAlias",code); // Å°½ºÅä¾î¿¡¼­ °³ÀÎÅ°¸¦ Àоî¿Ã¶§ ¾Ïȣȭ Å° ÄÚµå ÇÊ¿ä System.out.println("5.1 ¼Û½ÅÀÚÀÇ °³ÀÎÅ° Àоî¿À±â "); // 5.2 ¸Þ½ÃÁö ¼­¸íÇϱâ (SUD) String message = "ÀüÀÚ¼­¸í Å×½ºÆ®"; Charset charset = Charset.forName("UTF-8"); byte[] sigMessage = rsaSign(message.getBytes(charset), machinePrivateKey); // ¸Þ½ÃÁö¿¡ ´ëÇØ ±â±â°³ÀÎÅ°·Î ¼­¸í. // ¼­¸í°ªÀ» ÆÄÀÏ·Î ÀúÀå fos = new FileOutputStream(new File(senderName+machineName+".sig")); // ¼­¸í¹®À» ÆÄÀÏ·Î ÀúÀå fos.write(sigMessage); fos.close(); // ¸Þ½ÃÁö¿Í ¼­¸í¹®À» ÇÔ²² ¼ö½ÅÀÚ¿¡°Ô Àü¼Û (SUD->RUD) System.out.println("5.2 ÀüÀÚ¼­¸í°ª Àü¼Û "); // 5.3 ¼­¸í °ËÁõÇϱâ (RUD) // ¼Û½ÅÀÚ PKMSÀÇ ÀÎÁõ¼­ Àоî¿À±â (RUD) CertificateFactory cf = CertificateFactory.getInstance("X.509"); fis = new FileInputStream(new File(senderName+".der")); X509Certificate senderCert = (X509Certificate)cf.generateCertificate(fis); // ÆÄÀÏ¿¡¼­ Àо ÀÎÁõ¼­ Çü½ÄÀ¸·Î ÇÒ´ç fis.close(); // ÀÎÁõ±â°üÀÇ ÀÎÁõ¼­ Àоî¿À±â fis = new FileInputStream(new File("inter.der")); X509Certificate interCert = (X509Certificate)cf.generateCertificate(fis); // ÆÄÀÏ¿¡¼­ Àо ÀÎÁõ¼­ Çü½ÄÀ¸·Î ÇÒ´ç fis.close(); // ÀÎÁõ¼­ÀÇ À¯È¿¼º °ËÁõ senderCert.checkValidity(); senderCert.verify(interCert.getPublicKey()); // »ç¿ëÀÚ ÀÎÁõ¼­ÀÇ À¯È¿¼º °ËÁõ System.out.println(" - ¼Û½ÅÀÚ ÀÎÁõ¼­ÀÇ À¯È¿¼º °ËÁõ : "); // ¼Û½ÅÀÚÀÇ ±â±âÀÎÁõ¼­¸í Àоî¿À±â (RUD) fis = new FileInputStream(new File(senderName+machineName+".dsig")); size = fis.available(); s1 = new byte[size]; fis.read(s1); fis.close(); // ¼Û½ÅÀÚ ±â±âÀÇ °ø°³Å°¸¦ ÆÄÀÏ¿¡¼­ Àоî¿À±â (RUD) fis = new FileInputStream(new File(senderName+machineName+".pkey")); size = fis.available(); byte[] s = new byte[size]; fis.read(s); fis.close(); X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(s); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PublicKey machinePublicKey = keyFactory.generatePublic(pubKeySpec); // ¼Û½ÅÀÚÀÇ ±â±âÀÎÁõ¼­¸í °ËÁõ (RUD) m1 = (senderName+machineName).getBytes(charset); m2 = machinePublicKey.getEncoded(); result = rsaVerify(m1,m2,s1,senderCert.getPublicKey()); System.out.println(" - "+senderName+machineName+"ÀÇ ±â±âÀÎÁõ¼­¸í À¯È¿¼º °ËÁõ : "+result); // ¼ö½ÅµÈ ÆÄÀÏ¿¡¼­ ÀüÀÚ¼­¸í°ª Àоî¿À±â fis = new FileInputStream(new File(senderName+machineName+".sig")); size = fis.available(); s1 = new byte[size]; fis.read(s1); fis.close(); message = "ÀüÀÚ¼­¸í Å×½ºÆ®"; result = rsaVerify(message.getBytes(charset),s1,machinePublicKey); System.out.println(" - ÀüÀÚ¼­¸íÀÇ À¯È¿¼º °ËÁõ : "+result); System.out.println("5.3 ÀüÀÚ¼­¸í °ËÁõ ¿Ï·á "); System.out.println(); } // ¸Þ´º 6. »ç¿ëÀÚÀÇ ±â±â »çÀÌÀÇ ÀüÀÚºÀÅõ Å×½ºÆ® // ¼Û½ÅÀÚ ±â±â (SUD), ¼ö½ÅÀÚ ±â±â (RUD) °£ÀÇ ÇÁ·ÎÅäÄÝ // ¼Û½ÅÀÚ ±â±â´Â ÀÚ½ÅÀÇ ±â±âÀÇ °³ÀÎÅ°·Î ¼­¸íÇÏ°í ¼ö½ÅÀÚ ±â±âÀÇ °ø°³Å°·Î ¾ÏȣȭÇÏ¿© Àü¼Û // ¼ö½ÅÀÚ ±â±â´Â ÀÚ½ÅÀÇ ±â±âÀÇ °³ÀÎÅ°·Î º¹È£È­ÇÏ°í ¼Û½ÅÀÚ ±â±âÀÇ °ø°³Å°·Î ¼­¸íÀ» °ËÁõ public static void TestEnvelope(String senderName, String senderMachineName, String receiverName, String receiverMachineName) throws IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, SignatureException, NoSuchProviderException, InvalidKeySpecException { FileInputStream fis; FileOutputStream fos; KeyStore ks; byte[] m1; // »ç¿ëÀÚ¸í+±â±â¸í ¹ÙÀÌÆ®½ºÆ®¸² byte[] m2; // ±â±âÀÇ °ø°³Å° ¹ÙÀÌÆ®½ºÆ®¸² byte[] s0; // ±â±âÀÎÁõ¼­¸í byte[] s1=null; // ±â±âÀÎÁõ¼­¸í (ÆÄÀÏ¿¡¼­ Àоî¿Â °Í) boolean result; // ±â±âÀÎÁõ¼­¸í °ËÁõ °á°ú int size; // ÆÄÀÏ¿¡¼­ ¹ÙÀÌÆ®½ºÆ®¸² Àоî¿Ã¶§ Å©±â char[] code = {'s','e','c','r','e','t','c','o','d','e'}; // °³ÀÎÅ° ¾Ïȣȭ¸¦ À§ÇÑ Å° ÄÚµå ¼³Á¤. ÆíÀÇ»ó °íÁ¤ÇÏ¿´À½ // 6.1 ¼Û½ÅÀÚÀÇ Å° Àоî¿À±â (SUD) fis = new FileInputStream(new File(senderName+senderMachineName+".key")); ks = KeyStore.getInstance(KeyStore.getDefaultType()); ks.load(fis,code); // ÆÄÀÏ¿¡¼­ Àоî¿Í¼­ Å°½ºÅä¾î¿¡ ·Îµå fis.close(); PrivateKey senderMachinePrivateKey = (PrivateKey)ks.getKey(senderName+senderMachineName+"PrivateKeyAlias",code); // Å°½ºÅä¾î¿¡¼­ °³ÀÎÅ°¸¦ Àоî¿Ã¶§ ¾Ïȣȭ Å° ÄÚµå ÇÊ¿ä System.out.println(" - ¼Û½ÅÀÚÀÇ °³ÀÎÅ° Àоî¿À±â "); // ¼ö½ÅÀÚ PKMSÀÇ ÀÎÁõ¼­ Àоî¿À±â (RUD) CertificateFactory cf = CertificateFactory.getInstance("X.509"); fis = new FileInputStream(new File(receiverName+".der")); X509Certificate receiverCert = (X509Certificate)cf.generateCertificate(fis); // ÆÄÀÏ¿¡¼­ Àо ÀÎÁõ¼­ Çü½ÄÀ¸·Î ÇÒ´ç fis.close(); System.out.println(" - ¼ö½ÅÀÚÀÇ ÀÎÁõ¼­ Àоî¿À±â "); // ÀÎÁõ±â°üÀÇ ÀÎÁõ¼­ Àоî¿À±â fis = new FileInputStream(new File("inter.der")); X509Certificate interCert = (X509Certificate)cf.generateCertificate(fis); // ÆÄÀÏ¿¡¼­ Àо ÀÎÁõ¼­ Çü½ÄÀ¸·Î ÇÒ´ç fis.close(); System.out.println(" - ÀÎÁõ±â°üÀÇ ÀÎÁõ¼­ Àоî¿À±â "); // ÀÎÁõ¼­ÀÇ À¯È¿¼º °ËÁõ receiverCert.checkValidity(); receiverCert.verify(interCert.getPublicKey()); // »ç¿ëÀÚ ÀÎÁõ¼­ÀÇ À¯È¿¼º °ËÁõ System.out.println(" - ¼ö½ÅÀÚ ÀÎÁõ¼­ÀÇ À¯È¿¼º °ËÁõ : "); // ¼ö½ÅÀÚÀÇ ±â±âÀÎÁõ¼­¸í Àоî¿À±â (RUD) fis = new FileInputStream(new File(receiverName+receiverMachineName+".dsig")); size = fis.available(); s1 = new byte[size]; fis.read(s1); fis.close(); System.out.println(" - ¼ö½ÅÀÚÀÇ ±â±âÀÎÁõ¼­¸í Àоî¿À±â "); // ¼ö½ÅÀÚ ±â±âÀÇ °ø°³Å°¸¦ ÆÄÀÏ¿¡¼­ Àоî¿À±â (RUD) fis = new FileInputStream(new File(receiverName+receiverMachineName+".pkey")); size = fis.available(); byte[] s = new byte[size]; fis.read(s); fis.close(); X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(s); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PublicKey receiverMachinePublicKey = keyFactory.generatePublic(pubKeySpec); System.out.println(" - ¼ö½ÅÀÚÀÇ ±â±â°ø°³Å°¸¦ ÆÄÀÏ¿¡¼­ Àоî¿À±â "); // ¼ö½ÅÀÚÀÇ ±â±âÀÎÁõ¼­¸í °ËÁõ (RUD) m1 = (receiverName+receiverMachineName).getBytes(); m2 = receiverMachinePublicKey.getEncoded(); result = rsaVerify(m1,m2,s1,receiverCert.getPublicKey()); System.out.println(" - "+receiverName+receiverMachineName+"ÀÇ ±â±âÀÎÁõ¼­¸í À¯È¿¼º °ËÁõ : "+result); System.out.println("6.1 ¼Û½ÅÀÚÀÇ Å° Áغñ ¿Ï·á "); // 6.2 ÀüÀÚºÀÅõ »ý¼ºÇϱâ (SUD) // ¼Û½ÅÀÚ ±â±âÀÇ ±â±â°³ÀÎÅ°·Î ÀüÀÚ¼­¸í »ý¼º String message = "ÀüÀÚºÀÅõ Å×½ºÆ® (ÀüÀÚ¼­¸í+¾Ïȣȭ)"; Charset charset = Charset.forName("UTF-8"); byte[] sigMessage = rsaSign(message.getBytes(charset), senderMachinePrivateKey); // ¸Þ½ÃÁö¿¡ ´ëÇØ ±â±â°³ÀÎÅ°·Î ¼­¸í. // ¼­¸í°ªÀ» ÆÄÀÏ·Î ÀúÀå fos = new FileOutputStream(new File(senderName+senderMachineName+".sig")); // ¼­¸í¹®À» ÆÄÀÏ·Î ÀúÀå fos.write(sigMessage); fos.close(); System.out.println(" - ¼Û½ÅÀÚ±â±âÀÇ ±â±â°³ÀÎÅ°·Î ¼­¸í¹® »ý¼º "); // ¼ö½ÅÀÚ ±â±âÀÇ ±â±â°ø°³Å°·Î ¾Ïȣȭ byte[] ct; // ¾ÏÈ£¹® ct = rsaEncrypt(message.getBytes(charset), receiverMachinePublicKey); fos = new FileOutputStream(new File(receiverName+receiverMachineName+".enc")); // ¾ÏÈ£¹®À» ÆÄÀÏ·Î ÀúÀå fos.write(ct); fos.close(); System.out.println(" - ¼ö½ÅÀÚ±â±âÀÇ ±â±â°ø°³Å°·Î ¾ÏÈ£¹® »ý¼º "); // ¸Þ½ÃÁö+¼­¸í¹®+¾ÏÈ£¹®À» ÇÔ²² ¼ö½ÅÀÚ¿¡°Ô Àü¼Û (SUD->RUD) System.out.println("6.2 ÀüÀÚºÀÅõ(¸Þ½ÃÁö+¼­¸í¹®+¾ÏÈ£¹®)¸¦ ¼ö½ÅÀÚ¿¡°Ô Àü¼Û "); // 6.3 ÀüÀÚºÀÅõ °ËÁõÇϱâ (RUD) // ¼Û½ÅÀÚ PKMSÀÇ ÀÎÁõ¼­ Àоî¿À±â (RUD) cf = CertificateFactory.getInstance("X.509"); fis = new FileInputStream(new File(senderName+".der")); X509Certificate senderCert = (X509Certificate)cf.generateCertificate(fis); // ÆÄÀÏ¿¡¼­ Àо ÀÎÁõ¼­ Çü½ÄÀ¸·Î ÇÒ´ç fis.close(); // ÀÎÁõ±â°üÀÇ ÀÎÁõ¼­ Àоî¿À±â fis = new FileInputStream(new File("inter.der")); interCert = (X509Certificate)cf.generateCertificate(fis); // ÆÄÀÏ¿¡¼­ Àо ÀÎÁõ¼­ Çü½ÄÀ¸·Î ÇÒ´ç fis.close(); // ÀÎÁõ¼­ÀÇ À¯È¿¼º °ËÁõ senderCert.checkValidity(); senderCert.verify(interCert.getPublicKey()); // »ç¿ëÀÚ ÀÎÁõ¼­ÀÇ À¯È¿¼º °ËÁõ System.out.println(" - ¼Û½ÅÀÚ ÀÎÁõ¼­ÀÇ À¯È¿¼º °ËÁõ : "); // ¼Û½ÅÀÚÀÇ ±â±âÀÎÁõ¼­¸í Àоî¿À±â (RUD) fis = new FileInputStream(new File(senderName+senderMachineName+".dsig")); size = fis.available(); s1 = new byte[size]; fis.read(s1); fis.close(); // ¼Û½ÅÀÚ ±â±âÀÇ °ø°³Å°¸¦ ÆÄÀÏ¿¡¼­ Àоî¿À±â (RUD) fis = new FileInputStream(new File(senderName+senderMachineName+".pkey")); size = fis.available(); s = new byte[size]; fis.read(s); fis.close(); pubKeySpec = new X509EncodedKeySpec(s); keyFactory = KeyFactory.getInstance("RSA"); PublicKey senderMachinePublicKey = keyFactory.generatePublic(pubKeySpec); // ¼Û½ÅÀÚÀÇ ±â±âÀÎÁõ¼­¸í °ËÁõ (RUD) m1 = (senderName+senderMachineName).getBytes(charset); m2 = senderMachinePublicKey.getEncoded(); result = rsaVerify(m1,m2,s1,senderCert.getPublicKey()); System.out.println(" - "+senderName+senderMachineName+"ÀÇ ±â±âÀÎÁõ¼­¸í À¯È¿¼º °ËÁõ : "+result); // ¾ÏÈ£¹® Àоî¿Í¼­ º¹È£È­Çϱâ // ¾ÏÈ£¹®À» ÆÄÀÏ¿¡¼­ Àоî¿È fis = new FileInputStream(new File(receiverName+receiverMachineName+".enc")); size = fis.available(); byte[] ct1 = new byte[size]; fis.read(ct1); fis.close(); // ¼ö½ÅÀÚ ±â±âÀÇ °³ÀÎÅ° Àоî¿À±â. fis = new FileInputStream(new File(receiverName+receiverMachineName+".key")); ks = KeyStore.getInstance(KeyStore.getDefaultType()); ks.load(fis,code); // ÆÄÀÏ¿¡¼­ Àоî¿Í¼­ Å°½ºÅä¾î¿¡ ·Îµå fis.close(); PrivateKey receiverMachinePrivateKey = (PrivateKey)ks.getKey(receiverName+receiverMachineName+"PrivateKeyAlias",code); // Å°½ºÅä¾î¿¡¼­ °³ÀÎÅ°¸¦ Àоî¿Ã¶§ ¾Ïȣȭ Å° ÄÚµå ÇÊ¿ä byte[] pt1 = rsaDecrypt(ct1,receiverMachinePrivateKey); String decryptedText = new String(pt1, charset); System.out.println(" - º¹È£È­µÈ ¸Þ½ÃÁö : "+decryptedText); // ¼ö½ÅµÈ ÆÄÀÏ¿¡¼­ ÀüÀÚ¼­¸í°ª Àоî¿À±â fis = new FileInputStream(new File(senderName+senderMachineName+".sig")); size = fis.available(); s1 = new byte[size]; fis.read(s1); fis.close(); result = rsaVerify(message.getBytes(charset),s1,senderMachinePublicKey); System.out.println(" - ÀüÀÚ¼­¸íÀÇ À¯È¿¼º °ËÁõ : "+result); System.out.println("6.3 ÀüÀÚºÀÅõ °ËÁõ ¿Ï·á "); System.out.println(); } // MAIN ÇÔ¼ö public static void main(String[] args) throws IOException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidKeySpecException, UnrecoverableKeyException, InvalidKeyException, KeyStoreException, NoSuchAlgorithmException, CertificateException, SignatureException, NoSuchProviderException{ // BouncyCastle Provider Ãß°¡ Security.addProvider(new BouncyCastleProvider()); // ÇÁ·Î¹ÙÀÌ´õ Ãß°¡ // ÆÄÀÏ ÀúÀå½Ã È®ÀåÀÚ Á¤¸® // *.der : ÀÎÁõ¼­ // *.crl : ÀÎÁõ¼­Ãë¼Ò¸ñ·Ï // *.key : °³ÀÎÅ°¸¦ Å°½ºÅä¾î¿¡ ÀúÀå // *.pkey : °ø°³Å°¸¦ ¹ÙÀÌÆ®½ºÆ®¸²À¸·Î ÆÄÀÏ¿¡ ÀúÀå // *.rsig : ÀÎÁõ¼­¹ß±Þ¿äû¼­¸íÀ» ÆÄÀÏ¿¡ ÀúÀå // *.dsig : ±â±âÀÎÁõ¼­¸íÀ» ¹ÙÀÌÆ®½ºÆ®¸²À¸·Î ÆÄÀÏ¿¡ ÀúÀå // *.enc : ¾ÏÈ£¹®À» ¹ÙÀÌÆ®½ºÆ®¸²À¸·Î ÆÄÀÏ¿¡ ÀúÀå // *.sig : ¼­¸í¹®À» ¹ÙÀÌÆ®½ºÆ®¸²À¸·Î ÆÄÀÏ¿¡ ÀúÀå int choice=1; Scanner a = new Scanner(System.in); int b; String userName; String machineName; String senderName; String senderMachineName; String receiverName; String receiverMachineName; do { System.out.println(); System.out.println("PKMS ½Ã¹Ä·¹ÀÌÅÍ "); System.out.println("============= "); System.out.println("1. ÀÎÁõ±â°ü ¼³Á¤ (CA)"); System.out.println("2. »ç¿ëÀÚ ÀÎÁõ¼­ ¹ß±Þ (CA<->PKMS) "); System.out.println("3. »ç¿ëÀÚ ±â±â¿¡ ÀÚüȮÀåÀÎÁõ¼­¸í ¹ß±Þ (PKMS<->UD) "); System.out.println("4. ¾Ïȣȭ/º¹È£È­ Å×½ºÆ® (SUD->RUD)"); System.out.println("5. ¼­¸í/°ËÁõ Å×½ºÆ® (SUD->RUD)"); System.out.println("6. ÀüÀÚºÀÅõ Å×½ºÆ® (SUD->RUD)"); System.out.println("7. ³¡³»±â "); System.out.println(); System.out.print("¼±ÅÃÇØ ÁÖ¼¼¿ä : "); b = a.nextInt(); switch (b) { case 1: // 1. ÀÎÁõ±â°ü ¼³Á¤ System.out.println("1. ÀÎÁõ±â°ü ¼³Á¤ (CA)"); InitializeCA(); break; case 2: // 2. »ç¿ëÀÚ ÀÎÁõ¼­ ¹ß±Þ System.out.println("2. »ç¿ëÀÚ ÀÎÁõ¼­ ¹ß±Þ (CA<->PKMS) "); System.out.print(" - »ç¿ëÀÚ¸í : "); userName = a.next(); IssueCert(userName); break; case 3: // 3. »ç¿ëÀÚ ±â±â¿¡ ±â±âÀÎÁõ¼­¸í ¹ß±Þ System.out.println("3. »ç¿ëÀÚ ±â±â¿¡ ÀÚüȮÀåÀÎÁõ¼­¸í ¹ß±Þ (PKMS<->UD) "); System.out.print(" - »ç¿ëÀÚ¸í : "); userName = a.next(); System.out.print(" - »ç¿ëÀÚ±â±â¸í : "); machineName = a.next(); SetupDevice(userName, machineName); break; case 4: // 4. ¾Ïȣȭ/º¹È£È­ Å×½ºÆ® System.out.println("4. ¾Ïȣȭ/º¹È£È­ Å×½ºÆ® (SUD->RUD)"); System.out.print(" - ¼ö½ÅÀÚ¸í : "); userName = a.next(); System.out.print(" - ¼ö½ÅÀÚ±â±â¸í : "); machineName = a.next(); TestEncryption(userName, machineName); break; case 5: // 5. ¼­¸í/°ËÁõ Å×½ºÆ® System.out.println("5. ¼­¸í/°ËÁõ Å×½ºÆ® (SUD->RUD)"); System.out.print(" - ¼Û½ÅÀÚ¸í : "); userName = a.next(); System.out.print(" - ¼Û½ÅÀÚ±â±â¸í : "); machineName = a.next(); TestSignature(userName, machineName); break; case 6: // 6. ÀüÀÚºÀÅõ Å×½ºÆ® - ¼Û½ÅÀÚÀÇ ¼­¸í ÈÄ ¼ö½ÅÀÚÀÇ °ø°³Å°·Î ¾Ïȣȭ System.out.println("6. ÀüÀÚºÀÅõ Å×½ºÆ® (SUD->RUD)"); System.out.print(" - ¼Û½ÅÀÚ¸í : "); senderName = a.next(); System.out.print(" - ¼Û½ÅÀÚ±â±â¸í : "); senderMachineName = a.next(); System.out.print(" - ¼ö½ÅÀÚ¸í : "); receiverName = a.next(); System.out.print(" - ¼ö½ÅÀÚ±â±â¸í : "); receiverMachineName = a.next(); TestEnvelope(senderName, senderMachineName, receiverName, receiverMachineName); break; case 7: // 7. ³¡³»±â System.out.println("\nÇÁ·Î±×·¥À» Á¾·áÇÕ´Ï´Ù. °¨»çÇÕ´Ï´Ù. \n "); break; } } while (b!=7); } }