JavaRush /ื‘ืœื•ื’ Java /Random-HE /ืืจื›ื™ื˜ืงื˜ื•ืจืช ืงืจื™ืคื˜ื•ื’ืจืคื™ื” ืฉืœ Java: ื”ื™ื›ืจื•ืช ืจืืฉื•ื ื”
Viacheslav
ืจึธืžึธื”

ืืจื›ื™ื˜ืงื˜ื•ืจืช ืงืจื™ืคื˜ื•ื’ืจืคื™ื” ืฉืœ Java: ื”ื™ื›ืจื•ืช ืจืืฉื•ื ื”

ืคื•ืจืกื ื‘ืงื‘ื•ืฆื”
ืื‘ื˜ื—ืช ื—ื™ืœื•ืคื™ ื ืชื•ื ื™ื ื”ื™ื ืื—ื“ ื”ืžืืคื™ื™ื ื™ื ื”ื—ืฉื•ื‘ื™ื ื‘ื™ื•ืชืจ ืฉืœ ื™ื™ืฉื•ืžื™ื ืžื•ื“ืจื ื™ื™ื. ืžืื– ื™ืžื™ ืงื“ื, ืื ืฉื™ื ื”ื’ื™ืขื• ืขื ืฉื™ื˜ื•ืช ืขืจืžื•ืžื™ื•ืช, ืฉืขื ื”ืชืคืชื—ื•ืช ื”ืื ื•ืฉื•ืช ื”ืคื›ื• ืœื›ืœ ืžื“ืข ื”ืงืจื™ืคื˜ื•ื’ืจืคื™ื”. ื‘ืื•ืคืŸ ื˜ื‘ืขื™, ื’'ืื•ื•ื” ืœื ืขืžื“ื” ื‘ืฆื“ ื•ื”ืฆื™ืขื” ืœืžืคืชื—ื™ื ืืช ืืจื›ื™ื˜ืงื˜ื•ืจืช ื”-Java Cryptography Architecture (JCA). ืกืงื™ืจื” ื–ื• ืืžื•ืจื” ืœืชืช ืžื•ืฉื’ ืจืืฉื•ืŸ ื›ื™ืฆื“ ื–ื” ืขื•ื‘ื“.

ื”ึทืงื“ึธืžึธื”

ืื ื™ ืžืฆื™ืข ืœื ืกื•ืข ืื—ื•ืจื” ื‘ื–ืžืŸ. ืœืคื ื™ื ื• ืจื•ืžื ื”ืขืชื™ืงื”. ื•ืœืคื ื™ื ื• ื’ืื™ื•ืก ื™ื•ืœื™ื•ืก ืงื™ืกืจ, ืฉืฉื•ืœื— ืžืกืจ ืœืžืคืงื“ื™ื•. ื‘ื•ื ื ืจืื” ืžื” ื™ืฉ ื‘ื”ื•ื“ืขื” ื”ื–ื•:
ืืจื›ื™ื˜ืงื˜ื•ืจืช ืงืจื™ืคื˜ื•ื’ืจืคื™ื” ืฉืœ Java: ื”ื™ื›ืจื•ืช ืจืืฉื•ื ื” - 2
ืžื” ื–ื” ื™ื›ื•ืœ ืœื”ื™ื•ืช ืื•ืžืจ: "ะ•ะกะšะ•ะฃะ“ะฌะ“ะœะฅะ˜ะคะฏ ะ• ะฃะ›ะŸ"? ื‘ื•ืื• ื ืคืชื— ืืช Java Online Compiler, ืœืžืฉืœ: repl.it
class Main {
  public static void main(String[] args) {
    String code = "ะ•ะกะšะ•ะฃะ“ะฌะ“ะœะฅะ˜ะคะฏ ะ• ะฃะ›ะŸ";
    for (char symbol : code.toCharArray()) {
      if (symbol != ' ') {
        symbol = (char) (symbol - 3);
      }
      System.out.print(symbol);
    }
  }
}
ืœืคื ื™ื ื• ื”ื™ื™ืฉื•ื ื”ืคืฉื•ื˜ ื‘ื™ื•ืชืจ ืฉืœ ืฆื•ืคืŸ ืงื™ืกืจ. ืขืœ ืคื™ ืขื‘ื•ื“ืชื• ืฉืœ ื”ื”ื™ืกื˜ื•ืจื™ื•ืŸ ื”ืจื•ืžื™ ื”ืงื“ื•ื ืกื•ืื˜ื•ื ื™ื•ืก ื‘ืฉื "ื—ื™ื™ ืฉื ื™ื ืขืฉืจ ื”ืงื™ืกืจื™ื", ื›ืš ื‘ื“ื™ื•ืง ื”ืฆืคื™ืŸ ืงื™ืกืจ ื”ื•ื“ืขื•ืช ืœื’ื ืจืœื™ื ืฉืœื•. ื•ื–ื• ืื—ืช ื”ื”ืชื™ื™ื—ืกื•ื™ื•ืช ื”ืขืชื™ืงื•ืช ื‘ื™ื•ืชืจ ืœืฉื™ืžื•ืฉ ื‘ื“ื‘ืจ ื›ื–ื” ื›ืžื• ืงืจื™ืคื˜ื•ื’ืจืคื™ื” . ื”ืžื™ืœื” "ืงืจื™ืคื˜ื•ื’ืจืคื™ื”" ื‘ืื” ืžื”ืžื™ืœื™ื ื”ื™ื•ื•ื ื™ื•ืช ื”ืขืชื™ืงื•ืช "ื ืกืชืจ" ื•"ื›ืชื•ื‘", ื›ืœื•ืžืจ. ื–ื” ื”ืžื“ืข ืฉืœ ื˜ื›ื ื™ืงื•ืช ืคืจื˜ื™ื•ืช. ืœ-Java ื™ืฉ ืชืžื™ื›ื” ืžืฉืœื” ื‘ืงืจื™ืคื˜ื•ื’ืจืคื™ื” ื•ื”ื™ื ื ืงืจืืช Java Cryptography Architecture (JCA). ืืช ื”ืชื™ืื•ืจ ื ื™ืชืŸ ืœืžืฆื•ื ื‘ืชื™ืขื•ื“ ื”ืจืฉืžื™ ืฉืœ ืื•ืจืงืœ - " Java Cryptography Architecture (JCA) ". ืื ื™ ืžืฆื™ืข ืœืš ืœื‘ื“ื•ืง ืื™ืœื• ื”ื–ื“ืžื ื•ื™ื•ืช ืื ื• ืžืงื‘ืœื™ื ื”ื•ื“ื•ืช ืœ-JCA.
ืืจื›ื™ื˜ืงื˜ื•ืจืช ื’'ืื•ื•ื” ืงืจื™ืคื˜ื•ื’ืจืคื™ื”: ื”ื™ื›ืจื•ืช ืจืืฉื•ื ื” - 3

J.C.A.

ื›ืคื™ ืฉืœืžื“ื ื• ื‘ืขื‘ืจ, Java ืžืฆื™ืขื” ืืช ืืจื›ื™ื˜ืงื˜ื•ืจืช ื”ืงืจื™ืคื˜ื•ื’ืจืคื™ื” ืฉืœ Java (JCA) ืœืขื‘ื•ื“ื” ืขื ืงืจื™ืคื˜ื•ื’ืจืคื™ื”. ืืจื›ื™ื˜ืงื˜ื•ืจื” ื–ื• ืžื›ื™ืœื” API (ื›ืœื•ืžืจ ืงื‘ื•ืฆื” ืžืกื•ื™ืžืช ืฉืœ ืžืžืฉืงื™ื) ื•ืกืคืงื™ื (ืฉืžื™ื™ืฉืžื™ื ืื•ืชื):
ืืจื›ื™ื˜ืงื˜ื•ืจืช ืงืจื™ืคื˜ื•ื’ืจืคื™ื” ืฉืœ Java: ื”ื™ื›ืจื•ืช ืจืืฉื•ื ื” - 4
ื›ืคื™ ืฉืื•ืžืจ ื”ืชื™ืขื•ื“, " ืคืœื˜ืคื•ืจืžืช Java ื›ื•ืœืœืช ืžืกืคืจ ืกืคืงื™ื ืžื•ื‘ื ื™ื ". ื›ืœื•ืžืจ, ืคืœื˜ืคื•ืจืžืช Java ืžืกืคืงืช ืงื‘ื•ืฆื” ืฉืœ ืกืคืงื™ื ืžื•ื‘ื ื™ื ืื•ืชื ื ื™ืชืŸ ืœื”ืจื—ื™ื‘ ื‘ืžื™ื“ืช ื”ืฆื•ืจืš. ืืชื” ื™ื›ื•ืœ ืœืจืื•ืช ืืช ื–ื” ื‘ืขืฆืžืš:
import java.security.Provider;
import java.security.Security;
class Main {
  public static void main(String[] args) {
    Provider[] providers = Security.getProviders();
    for (Provider p : providers) {
      System.out.println(p.getName());
    }
  }
}
ืจื™ืฉื•ื ืกืคืง ืฆื“ ืฉืœื™ืฉื™ ื”ื•ื ืงืœ ืžืื•ื“. ืœื“ื•ื’ืžื”: Security.addProvider(new BouncyCastleProvider()); ื“ื•ื’ืžื” ื–ื• ืžื—ื‘ืจืช ืืช ืื—ื“ ื”ืกืคืงื™ื ื”ืžืคื•ืจืกืžื™ื ื‘ื™ื•ืชืจ - BouncyCastle . ืื‘ืœ ื‘ืกืงื™ืจื” ื–ื• ื ืฉืชืžืฉ ืจืง ื‘ื›ืœื™ื ื‘ืกื™ืกื™ื™ื, ืœืœื ืกืคืจื™ื•ืช ืฉืœ ืฆื“ ืฉืœื™ืฉื™. ื”ืžืกืžืš ื”ืจืืฉื™ ืฉืœื ื•: " ืืจื›ื™ื˜ืงื˜ื•ืจืช ื’'ืื•ื•ื” ืงืจื™ืคื˜ื•ื’ืจืคื™ื” (JCA) ". ื”ื‘ื ื” ื›ื™ืฆื“ ืคื•ืขืœืช JCA ืชืขื–ื•ืจ ืœืš ืœื”ื‘ื™ืŸ ื‘ื™ืชืจ ืงืœื•ืช ืืช ื”ื˜ื›ื ื•ืœื•ื’ื™ื•ืช ืฉื‘ื”ืŸ ื ืขืฉื” ืฉื™ืžื•ืฉ ืคืขื™ืœ ื‘ืื•ืชื• JCA. ืœื“ื•ื’ืžื”: HTTPS (ืจืื” " ืž-HTTP ืœ-HTTPS ").
ืืจื›ื™ื˜ืงื˜ื•ืจืช ืงืจื™ืคื˜ื•ื’ืจืคื™ื” ืฉืœ Java: ื”ื™ื›ืจื•ืช ืจืืฉื•ื ื” - 5

MessageDigest

ื”ื“ื‘ืจ ื”ืจืืฉื•ืŸ ืฉื”ื•ื–ื›ืจ ื‘ืชื™ืขื•ื“ JCA ื”ื•ื MessageDigest. ื‘ืื•ืคืŸ ื›ืœืœื™, Digest ื‘ืจื•ืกื™ืช ื™ื”ื™ื” ื–ื”ื” - ืชืงืฆื™ืจ ืชื•ืื ื‘ืžืฉืžืขื•ืชื• ืœ"ืกื™ื›ื•ื". ืื‘ืœ ื‘ื”ืฆืคื ื”, ืชืงืฆื™ืจ ื”ื•ื ืกื›ื•ื ื—ืฉื™ืฉ. ืืคืฉืจ ื’ื ืœื–ื›ื•ืจ ื‘ืงืœื•ืช ืฉื‘ืื ื’ืœื™ืช Digest ื™ื›ื•ืœ ืœื”ื™ื•ืช ืžืชื•ืจื’ื ื’ื ื›-digest. ืคืจื˜ื™ื ื ื•ืกืคื™ื ื ื™ืชืŸ ืœืžืฆื•ื ื‘ืชื™ืขื•ื“ JCA ื‘ืกืขื™ืฃ " MessageDigest ". ื›ืคื™ ืฉืื•ืžืจ ื”ืชื™ืขื•ื“, MessageDigest ืžื™ื™ืฆืจ ืชื•ืฆืื” ื‘ื’ื•ื“ืœ ืงื‘ื•ืข ืฉื ืงืจืืช digest ืื• hash. Hashing ื”ื™ื ืคื•ื ืงืฆื™ื” ื—ื“-ื›ื™ื•ื•ื ื™ืช, ื›ืœื•ืžืจ. ืื ื’ื™ื‘ืฉื ื• ืžืฉื”ื•, ืื– ืžื”ืชื•ืฆืื” (ื›ืœื•ืžืจ ืžื”-hash) ืœื ื ื•ื›ืœ ืœืงื‘ืœ ืืช ื”ืžืงื•ืจ ื”ืžืงื•ืจื™. ืื‘ืœ ืื ืื•ื‘ื™ื™ืงื˜ื™ื ื–ื”ื™ื ืขื•ื‘ืจื™ื ื’ื™ื‘ื•ื‘ (ืœื“ื•ื’ืžื”, ืžื—ืจื•ื–ื•ืช ืฉืœ ืชื•ื•ื™ื ื–ื”ื™ื), ืื– ื”ื’ื™ื‘ื•ื‘ ืฉืœื”ื ื—ื™ื™ื‘ ืœื”ืชืื™ื. ื›ืคื™ ืฉืฆื•ื™ืŸ ื‘ืชื™ืขื•ื“, ื—ืฉื™ืฉ ื›ื–ื” ื ืงืจื ืœืคืขืžื™ื ื’ื "ืฆ'ืง-ืกื•ื" ืื• "ื˜ื‘ื™ืขืช ืืฆื‘ืข ื“ื™ื’ื™ื˜ืœื™ืช" ืฉืœ ื ืชื•ื ื™ื. ื ื™ืชืŸ ืœื‘ืฆืข ื’ื™ื‘ื•ื‘ ื‘ืืžืฆืขื•ืช ืืœื’ื•ืจื™ืชืžื™ื ืฉื•ื ื™ื. ื ื™ืชืŸ ืœืจืื•ืช ืืœื’ื•ืจื™ืชืžื™ื ื–ืžื™ื ื™ื ื‘ืžืกืžืš " ืชื™ืขื•ื“ ืฉื ื”ืืœื’ื•ืจื™ืชื ื”ืกื˜ื ื“ืจื˜ื™ ืฉืœ Java Cryptography Architecture ืขื‘ื•ืจ JDK 8 ". ื‘ื•ื ื ืขืฉื” ืืช ื”ื’ื™ื‘ื•ื‘ ื•ื ื“ืคื™ืก ืืช ื”ื’ื™ื‘ื•ื‘ ืœืงื•ื ืกื•ืœื”:
import javax.xml.bind.DatatypeConverter;
import java.security.*;
public class Main {
  public static void main(String[] args) {
    try {
      MessageDigest digester = MessageDigest.getInstance("SHA-512");
      byte[] input = "Secret string".getBytes();
      byte[] digest = digester.digest(input);
      System.out.println(DatatypeConverter.printHexBinary(digest));
    } catch (NoSuchAlgorithmException e) {
      throw new IllegalStateException(e);
    }
  }
}
Hashing ื™ื›ื•ืœ ืœื”ื™ื•ืช ืฉื™ืžื•ืฉื™, ืœืžืฉืœ, ื‘ืขืช ืื—ืกื•ืŸ ืกื™ืกืžืื•ืช. ืžื›ื™ื•ื•ืŸ ืฉื ื™ืชืŸ ืœื‘ื“ื•ืง ืืช ื”-hash ืฉืœ ื”ืกื™ืกืžื” ืฉื”ื•ื–ื ื” ืžื•ืœ hash ืฉื ืฉืžืจ ื‘ืขื‘ืจ. ืื ื”-hashs ืชื•ืืžื™ื, ืื– ื’ื ื”ืกื™ืกืžื” ืชื•ืืžืช. ืœื’ื™ื‘ื•ื‘ ืžืื•ื‘ื˜ื— ืขื•ื“ ื™ื•ืชืจ, ื ืขืฉื” ืฉื™ืžื•ืฉ ื‘ืžื•ืฉื’ ืฉื ืงืจื "ืžืœื—". ื ื™ืชืŸ ืœื™ื™ืฉื ืืช ื”ืžืœื— ื‘ืืžืฆืขื•ืช ื”ืžื—ืœืงื” SecureRandom . ืœืคื ื™ ื‘ื™ืฆื•ืข ืฉื™ื˜ืช ื”ืขื™ื›ื•ืœ, ื‘ื•ืื• ื ืชืืจ ื”ื•ืกืคืช "ืžืœื—":
byte[] salt = new byte[16];
SecureRandom.getInstanceStrong().nextBytes(salt);
digester.update(salt);
ืื‘ืœ ื—ืฉื™ืฉ ื”ื•ื ืคื•ื ืงืฆื™ื” ื—ื“-ื›ื™ื•ื•ื ื™ืช. ืื‘ืœ ืžื” ืื ืืชื” ืจื•ืฆื” ืœื”ื™ื•ืช ืžืกื•ื’ืœ ืœื”ืฆืคื™ืŸ ื•ืœืคืขื ื—?
ืืจื›ื™ื˜ืงื˜ื•ืจืช ื’'ืื•ื•ื” ืงืจื™ืคื˜ื•ื’ืจืคื™ื”: ื”ื™ื›ืจื•ืช ืจืืฉื•ื ื” - 6

ืงืจื™ืคื˜ื•ื’ืจืคื™ื” ืฉืœ ืžืคืชื— ืกื™ืžื˜ืจื™

ื”ืฆืคื ื” ืกื™ืžื˜ืจื™ืช ื”ื™ื ื”ืฆืคื ื” ื”ืžืฉืชืžืฉืช ื‘ืื•ืชื• ืžืคืชื— ืœื”ืฆืคื ื” ื•ืœืคืขื ื•ื—. ืขืœ ืžื ืช ืœื”ืฉืชืžืฉ ื‘ื”ืฆืคื ื” ืกื™ืžื˜ืจื™ืช ืื ื• ื–ืงื•ืงื™ื ืœืžืคืชื—. ื›ื“ื™ ืœื”ืฉื™ื’ ื–ืืช ืื ื• ืžืฉืชืžืฉื™ื ื‘- KeyGenerator . ื‘ื ื•ืกืฃ, ื ืฆื˜ืจืš ืžื—ืœืงื” ืฉืžื™ื™ืฆื’ืช ืฆื•ืคืŸ ( Cipher ). ื›ืคื™ ืฉืฆื•ื™ืŸ ื‘ืชื™ืขื•ื“ JCA ื‘ืกืขื™ืฃ " ื™ืฆื™ืจืช ืื•ื‘ื™ื™ืงื˜ ืฆื•ืคืŸ ", ื›ื“ื™ ืœื™ืฆื•ืจ ืฆื•ืคืŸ ืืชื” ืฆืจื™ืš ืœืฆื™ื™ืŸ ืœื ืจืง ืืœื’ื•ืจื™ืชื, ืืœื "ื˜ืจื ืกืคื•ืจืžืฆื™ื”" ื‘ืฉื•ืจื”. ืชื™ืื•ืจ ื”ื˜ืจื ืกืคื•ืจืžืฆื™ื” ื ืจืื” ื›ืš: "ืืœื’ื•ืจื™ืชื/ืžืฆื‘/ืจื™ืคื•ื“":
  • ืืœื’ื•ืจื™ืชื : ื›ืืŸ ืื ื• ืžืกืชื›ืœื™ื ืขืœ ื”ืฉืžื•ืช ื”ืกื˜ื ื“ืจื˜ื™ื™ื ืขื‘ื•ืจ " ืืœื’ื•ืจื™ืชืžื™ื ืฉืœ ืฆื•ืคืŸ (ื”ืฆืคื ื”) . ืžื•ืžืœืฅ ืœื”ืฉืชืžืฉ ื‘-AES.
  • ืžืฆื‘ : ืžืฆื‘ ื”ืฆืคื ื”. ืœื“ื•ื’ืžื”: ECB ืื• CBC (ื ื“ื‘ืจ ืขืœ ื–ื” ืงืฆืช ืžืื•ื—ืจ ื™ื•ืชืจ)
  • ื”ื–ื—ื”/ืคื™ืฆื•ืœ : ื›ืœ ื‘ืœื•ืง ื ืชื•ื ื™ื ืžื•ืฆืคืŸ ื‘ื ืคืจื“. ืคืจืžื˜ืจ ื–ื” ืงื•ื‘ืข ื›ืžื” ื ืชื•ื ื™ื ื™ื™ืกืคืจื• ื›ื’ื•ืฉ ืื—ื“.
ืœื“ื•ื’ืžื”, ืงื— ืืช ื”ืฉื™ื ื•ื™ ื”ื‘ื: "AES/ECB/PKCS5Padding". ื›ืœื•ืžืจ, ืืœื’ื•ืจื™ืชื ื”ื”ืฆืคื ื” ื”ื•ื AES, ืžืฆื‘ ื”ื”ืฆืคื ื” ื”ื•ื ECB (ืงื™ืฆื•ืจ ืฉืœ Electronic Codebook), ื’ื•ื“ืœ ื”ื‘ืœื•ืง ื”ื•ื PKCS5Padding. PKCS5Padding ืื•ืžืจ ืฉื”ื’ื•ื“ืœ ืฉืœ ื‘ืœื•ืง ืื—ื“ ื”ื•ื 2 ื‘ืชื™ื (16 ืกื™ื‘ื™ื•ืช). ืžืฆื‘ ื”ื”ืฆืคื ื” ืฉืœ ืกืคืจ ืงื•ื“ื™ื ืืœืงื˜ืจื•ื ื™ ื›ื•ืœืœ ื”ืฆืคื ื” ืจืฆื™ืคื” ืฉืœ ื›ืœ ื‘ืœื•ืง:
ืืจื›ื™ื˜ืงื˜ื•ืจืช ืงืจื™ืคื˜ื•ื’ืจืคื™ื” ืฉืœ Java: ื”ื™ื›ืจื•ืช ืจืืฉื•ื ื” - 7
ื–ื” ืขืฉื•ื™ ืœื”ื™ืจืื•ืช ื›ืš ื‘ืงื•ื“:
import javax.xml.bind.DatatypeConverter;
import javax.crypto.*;
import java.security.Key;
public class Main {
  public static void main(String[] args) throws Exception {
    String text = "secret!!secret!!secret!!secret!!";
    // Generate new key
    KeyGenerator keygen = KeyGenerator.getInstance("AES");
    keygen.init(256);
    Key key = keygen.generateKey();
    // Encrypt with key
    String transformation = "AES/ECB/PKCS5Padding";
    Cipher cipher = Cipher.getInstance(transformation);
    cipher.init(Cipher.ENCRYPT_MODE, key);
    byte[] encrypted = cipher.doFinal(text.getBytes());
    System.out.println(DatatypeConverter.printHexBinary(encrypted));
    // Decrypt with key
    cipher.init(Cipher.DECRYPT_MODE, key);
    String result = new String(cipher.doFinal(encrypted));
    System.out.println(result);
  }
}
ืื ื ื‘ืฆืข, ื ืฆืคื” ืœืจืื•ืช ื—ื–ืจื”, ื›ื™ ืฆื™ื™ื ื• 32 ืชื•ื•ื™ื. ื”ืชื•ื•ื™ื ื”ืืœื” ืžืจื›ื™ื‘ื™ื 2 ื‘ืœื•ืงื™ื ืฉืœ 16 ืกื™ื‘ื™ื•ืช:
ืืจื›ื™ื˜ืงื˜ื•ืจืช ืงืจื™ืคื˜ื•ื’ืจืคื™ื” ืฉืœ Java: ื”ื™ื›ืจื•ืช ืจืืฉื•ื ื” - 8
ื›ื“ื™ ืœื”ื™ืžื ืข ืžื”ืฉืžืขื” ื—ื•ื–ืจืช ื‘ืžืงืจื” ื–ื”, ืขืœื™ืš ืœื”ืฉืชืžืฉ ื‘ืžืฆื‘ ืื—ืจ - Cipher Block Chaining (CBC). ืžืฆื‘ ื–ื” ืžืฆื™ื’ ืืช ื”ืจืขื™ื•ืŸ ืฉืœ ืืชื—ื•ืœ ื•ืงื˜ื•ืจ (ืžื™ื•ืฆื’ ืขืœ ื™ื“ื™ ื”ืžื—ืœืงื” IvParameterSpec). ื•ื’ื ื”ื•ื“ื•ืช ืœืžืฆื‘ ื”ื–ื”, ื”ืชื•ืฆืื” ืฉืœ ื™ืฆื™ืจืช ื”ื‘ืœื•ืง ื”ืื—ืจื•ืŸ ืชืฉืžืฉ ืœื™ืฆื™ืจืช ื”ื‘ื:
ืืจื›ื™ื˜ืงื˜ื•ืจืช Java Cryptography: ื”ื™ื›ืจื•ืช ืจืืฉื•ื ื” - 9
ื‘ื•ื ื ื›ืชื•ื‘ ืืช ื–ื” ื‘ืงื•ื“:
import javax.xml.bind.DatatypeConverter;
import javax.crypto.*;
import java.security.*;
import javax.crypto.spec.IvParameterSpec;
public class Main {
  public static void main(String[] args) throws Exception {
    // Initialization Vector
    SecureRandom random = SecureRandom.getInstanceStrong();
    byte[] rnd = new byte[16];
    random.nextBytes(rnd);
    IvParameterSpec ivSpec = new IvParameterSpec(rnd);
    // Prepare key
    KeyGenerator keygen = KeyGenerator.getInstance("AES");
    keygen.init(256);
    Key key = keygen.generateKey();
    // CBC
    String text = "secret!!secret!!secret!!secret!!";
    String transformation = "AES/CBC/PKCS5Padding";
    Cipher cipher = Cipher.getInstance(transformation);
    cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
    byte[] enc = cipher.doFinal(text.getBytes());
    System.out.println(DatatypeConverter.printHexBinary(enc));
    // Decrypt
    cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);
    String result = new String(cipher.doFinal(enc));
    System.out.println(result);
  }
}
ื›ืคื™ ืฉืื ื• ืจื•ืื™ื, ื›ืชื•ืฆืื” ืžื›ืš ืื™ื ื ื• ืจื•ืื™ื ื‘ืœื•ืงื™ ืฆื•ืคืŸ ื—ื•ื–ืจื™ื. ืžืกื™ื‘ื” ื–ื•, ืžืฆื‘ ECB ืื™ื ื• ืžื•ืžืœืฅ, ื›ื™ ืžืืคืฉืจ ืœืจืื•ืช ื—ื–ืจื•ืช ื•ืœื”ืฉืชืžืฉ ื‘ื™ื“ืข ื”ื–ื” ืœืคืขื ื•ื—. ืœืžื™ื“ืข ื ื•ืกืฃ ืขืœ ECB ื•-CBC, ืื ื™ ืžืžืœื™ืฅ ืœืš ืœืงืจื•ื ืืช ื”ื—ื•ืžืจ: " ืžืฆื‘ ืกืคืจ ืงื•ื“ื™ื ืืœืงื˜ืจื•ื ื™ ". ืื‘ืœ ืœื”ืฆืคื ื” ืกื™ืžื˜ืจื™ืช ื™ืฉ ื‘ืขื™ื” ื‘ืจื•ืจื” - ืืชื” ืฆืจื™ืš ืื™ื›ืฉื”ื• ืœื”ืขื‘ื™ืจ ืืช ื”ืžืคืชื— ืžืžื™ ืฉืžืฆืคื™ืŸ ืœื–ื” ืฉืžืฆืคื™ืŸ. ื•ืœืื•ืจืš ื”ื ืชื™ื‘ ื”ื–ื” ืืคืฉืจ ืœื™ื™ืจื˜ ืืช ื”ืžืคืชื— ื”ื–ื” ื•ืื– ื™ื”ื™ื” ืืคืฉืจ ืœื™ื™ืจื˜ ื ืชื•ื ื™ื. ื•ื”ืฆืคื ื” ืืกื™ืžื˜ืจื™ืช ื ื•ืขื“ื” ืœืคืชื•ืจ ื‘ืขื™ื” ื–ื•.
ืืจื›ื™ื˜ืงื˜ื•ืจืช ืงืจื™ืคื˜ื•ื’ืจืคื™ื” ืฉืœ Java: ื”ื™ื›ืจื•ืช ืจืืฉื•ื ื” - 10

ื”ืฆืคื ื” ืืกื™ืžื˜ืจื™ืช

ื”ืฆืคื ื” ืืกื™ืžื˜ืจื™ืช ืื• ืงืจื™ืคื˜ื•ื’ืจืคื™ื” ืฉืœ ืžืคืชื— ืฆื™ื‘ื•ืจื™ ื”ื™ื ืฉื™ื˜ืช ื”ืฆืคื ื” ื”ืžืฉืชืžืฉืช ื‘ื–ื•ื’ ืžืคืชื—ื•ืช: ืžืคืชื— ืคืจื˜ื™ (ืฉื ืฉืžืจ ื‘ืกื•ื“ ืžื›ื•ืœื) ื•ืžืคืชื— ืฆื™ื‘ื•ืจื™ (ื–ืžื™ืŸ ืœืฆื™ื‘ื•ืจ). ื”ืคืจื“ื” ื–ื• ื ื—ื•ืฆื” ืขืœ ืžื ืช ืœื”ื—ืœื™ืฃ ื‘ืฆื•ืจื” ืžืื•ื‘ื˜ื—ืช ืืช ื”ืžืคืชื— ื”ืฆื™ื‘ื•ืจื™ ื‘ื™ืŸ ื”ืฆื“ื“ื™ื ืœื—ื™ืœื•ืคื™ ื”ืžื™ื“ืข, ืชื•ืš ืฉืžื™ืจื” ืขืœ ื”ืžืคืชื— ื”ืกื•ื“ื™. ื›ืฉื™ื•ืฆืจื™ื ื–ื•ื’ ืžืคืชื—ื•ืช, KeyGenerator ื›ื‘ืจ ืœื ืžืกืคื™ืง ืœื ื•; ืื ื—ื ื• ืฆืจื™ื›ื™ื KeyPairGenerator . ื‘ื•ืื• ื ืกืชื›ืœ ืขืœ ื“ื•ื’ืžื”:
import javax.crypto.*;
import java.security.*;
public class Main {
  public static void main(String[] args) throws Exception {
    KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
    generator.initialize(1024);
    KeyPair keyPair = generator.generateKeyPair();
    // Encrypt with PRIVATE KEY
    Cipher cipher = Cipher.getInstance("RSA");
    cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic());
    byte[] data = cipher.doFinal("Hello!".getBytes());
    // Decrypt with PUBLIC KEY
    cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());
    byte[] result = cipher.doFinal(data);
    System.out.println(new String(result));
  }
}
ื—ืฉื•ื‘ ืœื”ื‘ื™ืŸ ื›ืืŸ ืฉื›ืืฉืจ ืžืฉืชืžืฉื™ื ื‘ื”ืฆืคื ื” ืืกื™ืžื˜ืจื™ืช, ืื ื• ืชืžื™ื“ ืžืฉืชืžืฉื™ื ื‘-KeyPair ื›ื“ื™ ืœื”ืฉืชืžืฉ ื‘ืžืคืชื— ืื—ื“ ืœื”ืฆืคื ื” ื•ื‘ืื—ืจ ืœืคืขื ื•ื—. ืืœื ื‘ื’ืœืœ ื ืงื•ื“ืช ื”ื”ืฆืคื ื” ื”ื™ื ืฉืจืง ื”ื ืžืขืŸ ื™ื›ื•ืœ ืœืคืขื ื— ืื•ืชื”; ื”ื™ื ืžื•ืฆืคื ืช ืขื ืžืคืชื— ืฆื™ื‘ื•ืจื™, ื•ืžืคืขื ื—ืช ืจืง ืขื ืžืคืชื— ืคืจื˜ื™.
ืืจื›ื™ื˜ืงื˜ื•ืจืช ื’'ืื•ื•ื” ืงืจื™ืคื˜ื•ื’ืจืคื™ื”: ื”ื™ื›ืจื•ืช ืจืืฉื•ื ื” - 11

ื—ืชื™ืžื” ื“ื™ื’ื™ื˜ืœื™ืช

ื›ืคื™ ืฉืจืื™ื ื• ืœืžืขืœื”, ื‘ื”ื›ืจืช ื”ืžืคืชื— ื”ืฆื™ื‘ื•ืจื™, ื ื™ืชืŸ ืœืฉืœื•ื— ื ืชื•ื ื™ื ื›ืš ืฉืจืง ื”ื‘ืขืœื™ื ืฉืœ ื”ืžืคืชื— ื”ืคืจื˜ื™ ื™ื•ื›ืœ ืœืคืขื ื— ืื•ืชื. ื›ืœื•ืžืจ, ื”ืžื”ื•ืช ืฉืœ ื”ืฆืคื ื” ืืกื™ืžื˜ืจื™ืช ื”ื™ื ืฉื›ืœ ืื—ื“ ืžืฆืคื™ืŸ, ืื‘ืœ ืจืง ืื ื—ื ื• ืงื•ืจืื™ื. ื™ืฉื ื• ื’ื ื”ืœื™ืš ื”ืคื•ืš - ื—ืชื™ืžื” ื“ื™ื’ื™ื˜ืœื™ืช, ื”ืžื™ื•ืฆื’ืช ืขืœ ื™ื“ื™ ื”ืžื—ืœืงื” Signature . ื—ืชื™ืžื” ื“ื™ื’ื™ื˜ืœื™ืช ื™ื›ื•ืœื” ืœื”ืฉืชืžืฉ ื‘ืืœื’ื•ืจื™ืชืžื™ื ื”ื‘ืื™ื: " ืืœื’ื•ืจื™ืชืžื™ ื—ืชื™ืžื” ". ืชื™ืขื•ื“ JCA ืžืฆื™ืข ืœื”ืกืชื›ืœ ืžืงืจื•ื‘ ืขืœ ืฉื ื™ ืืœื”: DSAwithMD5 ื•-RSAwithMD5 ืžื” ื˜ื•ื‘ ื™ื•ืชืจ ืž-DSA ืื• RSA ื•ืžื” ื”ื”ื‘ื“ืœ ื‘ื™ื ื™ื”ื ืชื•ื›ืœื• ืœืงืจื•ื ื›ืืŸ: " ืื™ื–ื” ืขื•ื‘ื“ ื”ื›ื™ ื˜ื•ื‘ ืขื‘ื•ืจ ื”ืขื‘ืจื•ืช ืงื‘ืฆื™ื ืžื•ืฆืคื ื•ืช - RSA ืื• DSA? ". ืื• ืงืจื ืืช ื”ื“ื™ื•ื ื™ื ื›ืืŸ: " RSA ืœืขื•ืžืช DSA ืขื‘ื•ืจ ืžืคืชื—ื•ืช ืื™ืžื•ืช SSH ". ืื–, ื—ืชื™ืžื” ื“ื™ื’ื™ื˜ืœื™ืช. ื ืฆื˜ืจืš, ื›ืžื• ืงื•ื“ื, KeyPair ื•ืžื—ืœืงืช Signature ื—ื“ืฉื”. ืื ื‘ื“ืงืชื ืขื“ ื›ื” ื‘ืžื”ื“ืจื™ื ืžืงื•ื•ื ื™ื, ื”ื“ื•ื’ืžื” ื”ื‘ืื” ืขืฉื•ื™ื” ืœื”ื™ื•ืช ืžืขื˜ ืงืฉื” ืขื‘ื•ืจื. ื”ื“ื•ื’ืžื” ืฉืœื™ ืจืฆื” ืจืง ื›ืืŸ: rextester.com . ืื ื• ืžื™ื™ื‘ืื™ื ืืช ื”ืฉื™ืขื•ืจื™ื ืฉืื ื• ืฆืจื™ื›ื™ื:
import javax.crypto.*;
import java.security.*;
ืื ื• ื’ื ื ืฉื›ืชื‘ ืืช ื”ืฉื™ื˜ื” ื”ืขื™ืงืจื™ืช:
public static void main(String[] args) throws Exception {
    // Generate keys
    KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
    SecureRandom random = SecureRandom.getInstanceStrong();
    generator.initialize(2048, random);
    KeyPair keyPair = generator.generateKeyPair();
    // Digital Signature
    Signature dsa = Signature.getInstance("SHA256withRSA");
    dsa.initSign(keyPair.getPrivate());
    // Update and sign the data
    Cipher cipher = Cipher.getInstance("RSA");
    cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic());
    byte[] data = cipher.doFinal("Hello!".getBytes());
    dsa.update(data);
    byte[] signature = dsa.sign();
    // Verify signature
    dsa.initVerify(keyPair.getPublic());
    dsa.update(data);
    boolean verifies = dsa.verify(signature);
    System.out.println("Signature is ok: " + verifies);
    // Decrypt if signature is correct
    if (verifies) {
      cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());
      byte[] result = cipher.doFinal(data);
      System.out.println(new String(result));
    }
}
ื›ืš ืขื•ื‘ื“ืช ื—ืชื™ืžื” ื“ื™ื’ื™ื˜ืœื™ืช. ื—ืชื™ืžื” ื“ื™ื’ื™ื˜ืœื™ืช ื”ื™ื ื ื•ืฉื ืžืขื ื™ื™ืŸ. ืื ื™ ืžืžืœื™ืฅ ืœืš ืœืขื™ื™ืŸ ื‘ื“ื•ื— ื‘ื ื•ืฉื ื–ื”:
ืืจื›ื™ื˜ืงื˜ื•ืจืช ื’'ืื•ื•ื” ืงืจื™ืคื˜ื•ื’ืจืคื™ื”: ื”ื™ื›ืจื•ืช ืจืืฉื•ื ื” - 12
ืœืขื™ืœ ืจืื™ื ื• ื›ื™ืฆื“ ื”ืฆื“ื“ื™ื ืžื—ืœื™ืคื™ื ื ืชื•ื ื™ื. ื”ืื ืื™ืŸ ืžืžืฉืง ืกื˜ื ื“ืจื˜ื™ ืœืื™ื ื˜ืจืืงืฆื™ื” ื”ื–ื• ืžืกื•ืคืง ื‘-JCA? ืžืกืชื‘ืจ ืฉื™ืฉ. ื‘ื•ืื• ื ืกืชื›ืœ ืขืœ ื–ื”.
ืืจื›ื™ื˜ืงื˜ื•ืจืช ื’'ืื•ื•ื” ืงืจื™ืคื˜ื•ื’ืจืคื™ื”: ื”ื™ื›ืจื•ืช ืจืืฉื•ื ื” - 13

ื”ืกื›ื ืžืคืชื—

ื”-Java Cryptography Architecture ืžืฆื™ื’ื” ื›ืœื™ ื—ืฉื•ื‘ - ื”ืกื›ื ืžืคืชื— ื”ื•ื ืคืจื•ื˜ื•ืงื•ืœ. ื”ื•ื ืžื™ื•ืฆื’ ืขืœ ื™ื“ื™ ืžื—ืœืงืช KeyAgreement . ื›ืคื™ ืฉืฆื•ื™ืŸ ื‘ืชื™ืขื•ื“ JCA, ืคืจื•ื˜ื•ืงื•ืœ ื–ื” ืžืืคืฉืจ ืœืžืกืคืจ ืฆื“ื“ื™ื ืœื”ื’ื“ื™ืจ ืืช ืื•ืชื• ืžืคืชื— ืงืจื™ืคื˜ื•ื’ืจืคื™ ืžื‘ืœื™ ืœืฉืชืฃ ืžื™ื“ืข ืกื•ื“ื™ ื›ืœืฉื”ื• ื‘ื™ืŸ ื”ืฆื“ื“ื™ื. ื ืฉืžืข ืžื•ื–ืจ? ืื– ื‘ื•ืื• ื ืกืชื›ืœ ืขืœ ื“ื•ื’ืžื”:
// 1. ะžะดะฝะฐ ะธะท ัั‚ะพั€ะพะฝ (ะะปะธัะฐ) ะณะตะฝะตั€ะธั€ัƒะตั‚ ะฟะฐั€ัƒ ะบะปัŽั‡ะตะน. Encoded ะฟัƒะฑะปะธั‡ะฝั‹ะน ะบะปัŽั‡ ะพั‚ะดะฐั‘ั‚.
KeyPairGenerator generator = KeyPairGenerator.getInstance("DH");
KeyPair aliceKeyPair = generator.generateKeyPair();
byte[] alicePubKeyEncoded = aliceKeyPair.getPublic().getEncoded();

// 2. ะ”ั€ัƒะณะฐั ัั‚ะพั€ะพะฝะฐ (ะฝะฐะฟั€ะธะผะตั€, ะ‘ะพะฑ) ะฟะพะปัƒั‡ะฐะตั‚ ะพั‚ะบั€ั‹ั‚ั‹ะน ะบะปัŽั‡ ะะปะธัั‹
KeyFactory bobKeyFactory = KeyFactory.getInstance("DH");
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(alicePubKeyEncoded);
PublicKey alicePubKey = bobKeyFactory.generatePublic(x509KeySpec);
// ะŸะฐั€ะฐะผะตั‚ั€ั‹, ะบะพั‚ะพั€ั‹ะต ะธัะฟะพะปัŒะทะพะฒะฐะปะฐ ะะปะธัะฐ ะฟั€ะธ ะณะตะฝะตั€ะฐั†ะธะธ ะบะปัŽั‡ะตะน
DHParameterSpec dhParamFromAlicePubKey = ((DHPublicKey)alicePubKey).getParams();
// ะกะพะทะดะฐั‘ั‚ ัะฒะพัŽ ะฟะฐั€ัƒ ะบะปัŽั‡ะตะน. ะžั‚ะดะฐั‘ั‚ ัะฒะพะน Encoded ะพั‚ะบั€ั‹ั‚ั‹ะน ะบะปัŽั‡
KeyPairGenerator bobKpairGen = KeyPairGenerator.getInstance("DH");
bobKpairGen.initialize(dhParamFromAlicePubKey);
KeyPair bobKeyPair = bobKpairGen.generateKeyPair();
byte[] bobPubKeyEncoded = bobKeyPair.getPublic().getEncoded();

ะขะตะฟะตั€ัŒ, ัƒ ะะปะธัั‹ ะตัั‚ัŒ ะพั‚ะบั€ั‹ั‚ั‹ะน ะบะปัŽั‡ ะ‘ะพะฑะฐ, ะฐ ัƒ ะ‘ะพะฑะฐ ะตัั‚ัŒ ะพั‚ะบั€ั‹ั‚ั‹ะน ะบะปัŽั‡ ะะปะธัั‹. What ะดะฐะปัŒัˆะต?
ะšะฐะบ ัะบะฐะทะฐะฝะพ ะฒ documentะฐั†ะธะธ JCA, ัƒ ะฝะฐั ะตัั‚ัŒ ะธะฝัั‚ั€ัƒะผะตะฝั‚ KeyAgreement, https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html#KeyAgreement ะบะพั‚ะพั€ั‹ะน ะฟะพะทะฒะพะปัะตั‚ ัƒัั‚ะฐะฝะพะฒะธั‚ัŒ ะพะดะธะฝะฐะบะพะฒั‹ะต ะบะปัŽั‡ะธ ัˆะธั„ั€ะพะฒะฐะฝะธั ะฑะตะท ะฝะตะพะฑั…ะพะดะธะผะพัั‚ะธ ะพะฑะผะตะฝะธะฒะฐั‚ัŒัั ัะตะบั€ะตั‚ะฝะพะน ะธะฝั„ะพั€ะผะฐั†ะธะตะน (ั‚.ะต. ะฑะตะท ะพะฑะผะตะฝะฐ private key). ะกะพะณะปะฐัˆะตะฝะธะต ะฒั‹ะณะปัะดะธั‚ ัะปะตะดัƒัŽั‰ะธะผ ะพะฑั€ะฐะทะพะผ:
// 3. ะกะพะณะปะฐัˆะตะฝะธะต ะฟะพ ะฟั€ะพั‚ะพะบะพะปัƒ ะ”ะธั„ั„ะธ-ะฅะตะปะปะผะฐะฝะฐ (Diffieโ€“Hellman, DH)
KeyAgreement aliceKeyAgree = KeyAgreement.getInstance("DH");
aliceKeyAgree.init(aliceKeyPair.getPrivate());
// ะะปะธัะฐ ะฝะฐ ะพัะฝะพะฒะต ะบะปัŽั‡ะฐ ะฑะพะฑะฐ ะธ ัะฒะพะตะณะพ private key ัะพะทะดะฐั‘ั‚ ะพะฑั‰ะธะน shared ะบะปัŽั‡
KeyFactory aliceKeyFactory = KeyFactory.getInstance("DH");
x509KeySpec = new X509EncodedKeySpec(bobPubKeyEncoded);
PublicKey bobPubKey = aliceKeyFactory.generatePublic(x509KeySpec);
aliceKeyAgree.doPhase(bobPubKey, true);
byte[] aliceSharedSecret = aliceKeyAgree.generateSecret();
SecretKeySpec aliceAesKey = new SecretKeySpec(aliceSharedSecret, 0, 16, "AES");
// ะ‘ะพะฑ ะฝะฐ ะพัะฝะพะฒะต ะบะปัŽั‡ะฐ ะะปะธัั‹ ะธ ัะฒะพะตะณะพ private key ัะพะทะดะฐั‘ั‚ ะพะฑั‰ะธะน shared ะบะปัŽั‡
KeyAgreement bobKeyAgree = KeyAgreement.getInstance("DH");
bobKeyAgree.init(bobKeyPair.getPrivate());
bobKeyAgree.doPhase(alicePubKey, true);
byte[] bobSharedSecret = bobKeyAgree.generateSecret();
SecretKeySpec bobAesKey = new SecretKeySpec(bobSharedSecret, 0, 16, "AES");
// ะžะฑั‰ะธะน ะบะปัŽั‡ ัƒ ะะปะธัั‹ ะธ ะ‘ะพะฑะฐ ะพะดะธะฝะฐะบะพะฒ
System.out.println("Shared keys are equals: " + Arrays.equals(aliceSharedSecret, bobSharedSecret));

ะ”ะฐะปะตะต ะ‘ะพะฑ ะธ ะะปะธัะฐ, ะธัะฟะพะปัŒะทัƒั ะพะฑั‰ะธะน ะบะปัŽั‡, ะฟั€ะพ ะบะพั‚ะพั€ั‹ะน ะฑะพะปัŒัˆะต ะฝะธะบั‚ะพ ะฝะต ะทะฝะฐะตั‚, ะพะฑะผะตะฝะธะฒะฐัŽั‚ัั ะทะฐัˆะธั„ั€ะพะฒะฐะฝะฝั‹ะผะธ ะดะฐะฝะฝั‹ะผะธ:
// 4. ะ‘ะพะฑ ัˆะธั„ั€ัƒะตั‚ ัะพะพะฑั‰ะตะฝะธะต ะดะปั ะะปะธัั‹
Cipher bobCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
bobCipher.init(Cipher.ENCRYPT_MODE, bobAesKey);
byte[] ciphertext = bobCipher.doFinal("Hello, Alice!".getBytes());
// ะŸะตั€ะตะดะฐั‘ั‚ ะะปะธัะต ะฟะฐั€ะฐะผะตั‚ั€ั‹, ั ะบะพั‚ะพั€ั‹ะผะธ ะฒั‹ะฟะพะปะฝัะปะฐััŒ ัˆะธั„ั€ะพะฒะบะฐ
byte[] encodedParamsFromBob = bobCipher.getParameters().getEncoded();

// 5. ะะปะธัะฐ ะฟั€ะธะฝะธะผะฐะตั‚ ัะพะพะฑั‰ะตะฝะธะต ะธ ั€ะฐััˆะธั„ั€ะพะฒั‹ะฒะฐะตั‚ ะตะณะพ
AlgorithmParameters aesParams = AlgorithmParameters.getInstance("AES");
aesParams.init(encodedParamsFromBob);
Cipher aliceCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
aliceCipher.init(Cipher.DECRYPT_MODE, aliceAesKey, aesParams);
byte[] recovered = aliceCipher.doFinal(ciphertext);
System.out.println(new String(recovered));
ื“ื•ื’ืžื” ื–ื• ื ืœืงื—ื” ืžื“ื•ื’ืžื ื”ืชื™ืขื•ื“ ืฉืœ JCA: " ื—ื™ืœื•ืคื™ ืžืคืชื—ื•ืช ื“ื™ืคื™-ื”ืœืžืŸ ื‘ื™ืŸ 2 ืฆื“ื“ื™ื ". ื›ืš ื ืจืื™ืช ื‘ืขืจืš ื”ืฆืคื ื” ื-ืกื™ืžื˜ืจื™ืช ื‘ืืจื›ื™ื˜ืงื˜ื•ืจืช ื”-Java Cryptography ื‘ืืžืฆืขื•ืช ืคืจื•ื˜ื•ืงื•ืœ Key Agreement. ืœืžื™ื“ืข ื ื•ืกืฃ ืขืœ ื”ืฆืคื ื” ืืกื™ืžื˜ืจื™ืช, ืกืจื˜ื•ื ื™ื ืžื•ืžืœืฆื™ื:
ืืจื›ื™ื˜ืงื˜ื•ืจืช ื’'ืื•ื•ื” ืงืจื™ืคื˜ื•ื’ืจืคื™ื”: ื”ื™ื›ืจื•ืช ืจืืฉื•ื ื” - 14

ืชืขื•ื“ื•ืช

ื•ื‘ื›ืŸ, ืœืงื™ื ื•ื— ื™ืฉ ืœื ื• ืขื“ื™ื™ืŸ ืžืฉื”ื• ืœื ืคื—ื•ืช ื—ืฉื•ื‘ - ืชืขื•ื“ื•ืช. ื‘ื“ืจืš ื›ืœืœ, ืื™ืฉื•ืจื™ื ื ื•ืฆืจื™ื ื‘ืืžืฆืขื•ืช ื›ืœื™ ื”ืฉื™ืจื•ืช keytool ื”ื›ืœื•ืœ ื‘-jdk. ืืชื” ื™ื›ื•ืœ ืœืงืจื•ื ืคืจื˜ื™ื ื ื•ืกืคื™ื, ืœืžืฉืœ, ื›ืืŸ: " ื™ืฆื™ืจืช ืชืขื•ื“ืช SSL ื‘ื—ืชื™ืžื” ืขืฆืžื™ืช ื‘ืืžืฆืขื•ืช ืคืงื•ื“ืช Java keytool ". ืืชื” ื™ื›ื•ืœ ื’ื ืœืงืจื•ื ืืช ื”ืžื“ืจื™ื›ื™ื ืฉืœ ืื•ืจืงืœ. ืœื“ื•ื’ืžื”, ื›ืืŸ: " ื›ื“ื™ ืœื”ืฉืชืžืฉ ื‘ื›ืœื™ ืžืคืชื— ืœื™ืฆื™ืจืช ืื™ืฉื•ืจ ืฉืจืช ". ืœื“ื•ื’ืžื”, ื‘ื•ืื• ื ืฉืชืžืฉ ื‘- Tutorialspoint Java Online Compiler :
import sun.security.tools.keytool.CertAndKeyGen;
import sun.security.x509.*;
import java.security.cert.*;
import java.security.*;
// Compiler args: -XDignore.symbol.file
public class Main {
  public static void main(String[] args) throws Exception {
    CertAndKeyGen certGen = new CertAndKeyGen("RSA", "SHA256WithRSA", null);
    // generate it with 2048 bits
    certGen.generate(2048);
    PrivateKey privateKey = certGen.getPrivateKey();
    X509Key publicKey = certGen.getPublicKey();
    // prepare the validity of the certificate
    long validSecs = (long) 365 * 24 * 60 * 60; // valid for one year
    // enter your details according to your application
    X500Name principal = new X500Name("CN=My Application,O=My Organisation,L=My City,C=DE");
    // add the certificate information, currently only valid for one year.
    X509Certificate cert = certGen.getSelfCertificate(principal, validSecs);
    // Public Key from Cert equals Public Key from generator
    PublicKey publicKeyFromCert = cert.getPublicKey();
    System.out.println(publicKeyFromCert.equals(publicKey));
  }
}
ื›ืคื™ ืฉืื ื• ื™ื›ื•ืœื™ื ืœืจืื•ืช, ืชืขื•ื“ื” ืžืกืคืงืช ืืช ื”ื™ื›ื•ืœืช ืœืกืคืง ืžืคืชื— ืฆื™ื‘ื•ืจื™. ืœืฉื™ื˜ื” ื–ื• ื™ืฉ ื—ื™ืกืจื•ืŸ - ืื ื• ืžืฉืชืžืฉื™ื sun.securityื‘- ืฉื ื—ืฉื‘ ืžืกื•ื›ืŸ, ื›ื™... ื—ื‘ื™ืœื” ื–ื• ืื™ื ื” ื—ืœืง ืžืžืžืฉืง ื”-API ื”ืฆื™ื‘ื•ืจื™ ืฉืœ Java. ืœื›ืŸ ื‘ืžื”ืœืš ื”ื”ื™ื“ื•ืจ ื™ืฉ ืฆื•ืจืš ืœืฆื™ื™ืŸ ืืช ื”ืคืจืžื˜ืจ - XDignore.symbol.file. ื™ืฉ ื“ืจืš ื ื•ืกืคืช - ืœื™ืฆื•ืจ ืชืขื•ื“ื” ื‘ืื•ืคืŸ ื™ื“ื ื™. ื”ื—ื™ืกืจื•ืŸ ื”ื•ื ืฉื”ื•ื ืžืฉืชืžืฉ ื‘-API ืคื ื™ืžื™ ืฉืื™ื ื• ืžืชื•ืขื“. ืขื ื–ืืช, ื›ื“ืื™ ืœื“ืขืช ืขืœ ื›ืš. ืœื›ืœ ื”ืคื—ื•ืช, ื›ื™ ื–ื” ื ืจืื” ื‘ื‘ื™ืจื•ืจ ื›ื™ืฆื“ ื ืขืฉื” ืฉื™ืžื•ืฉ ื‘ืžืคืจื˜ RFC-2459: " Internet X.509 Public Key Infrastructure ". ื”ื ื” ื“ื•ื’ืžื”:
// 1. ะ“ะตะฝะตั€ะธั€ัƒะตะผ ะฟะฐั€ัƒ ะบะปัŽั‡ะตะน
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(4096);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
// 2. ะžะฟั€ะตะดะตะปัะตะผ ะดะฐะฝะฝั‹ะต ัะตั€ั‚ะธั„ะธะบะฐั‚ะฐ
// ะžะฟั€ะตะดะตะปัะตะผ ัั€ะพะบ ะดะตะนัั‚ะฒะธั ัะตั€ั‚ะธั„ะธะบะฐั‚ะฐ
Date from = new Date();
Date to = new Date(from.getTime() + 365 * 1000L * 24L * 60L * 60L);
CertificateValidity interval = new CertificateValidity(from, to);
// ะžะฟั€ะตะดะตะปัะตะผ subject name, ั‚.ะต. Name ั‚ะพะณะพ, ั ั‡ะตะผ ะฐััะพั†ะธะธั€ะพะฒะฐะฝ ะฟัƒะฑะปะธั‡ะฝั‹ะน ะบะปัŽั‡
// CN = Common Name. ะงะตั€ะตะท ั‚ะพั‡ะบัƒ ั ะทะฐะฟัั‚ะพะน ะผะพะณัƒั‚ ะฑั‹ั‚ัŒ ัƒะบะฐะทะฐะฝั‹ ั‚ะฐะบะถะต ะดั€ัƒะณะธะต ะฐั‚ั€ะธะฑัƒั‚ั‹
// ะกะผ. https://docs.oracle.com/cd/E24191_01/common/tutorials/authz_cert_attributes.html
X500Name owner = new X500Name("cn=Unknown");
// ะฃะฝะธะบะฐะปัŒะฝั‹ะน ะฒ ะฟั€ะตะดะตะปะฐั… CA, ั‚.ะต. Certificate Authority (ั‚ะพั‚, ะบั‚ะพ ะฒั‹ะดะฐั‘ั‚ ัะตั€ั‚ะธั„ะธะบะฐั‚) ะฝะพะผะตั€
BigInteger number = new BigInteger(64, new SecureRandom());
CertificateSerialNumber serialNumber = new CertificateSerialNumber(number);
// ะžะฟั€ะตะดะตะปัะตะผ ะฐะปะณะพั€ะธั‚ะผ ะฟะพะดะฟะธัะธ ัะตั€ั‚ะธั„ะธะบะฐั‚ะฐ
AlgorithmId algorithmId = new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid);
CertificateAlgorithmId certificateAlgorithmId = new CertificateAlgorithmId(algorithmId);
// 3. ะŸะพ ะฟะพะดะณะพั‚ะพะฒะปะตะฝะฝะพะน ะธะฝั„ะพั€ะผะฐั†ะธะธ ัะพะทะดะฐั‘ะผ ัะตั€ั‚ะธั„ะธะบะฐั‚
X509CertInfo info = new X509CertInfo();
info.set(X509CertInfo.VALIDITY, interval);
info.set(X509CertInfo.SERIAL_NUMBER, serialNumber);
info.set(X509CertInfo.SUBJECT, owner);
info.set(X509CertInfo.ISSUER, owner);
info.set(X509CertInfo.KEY, new CertificateX509Key(keyPair.getPublic()));
info.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3));
info.set(X509CertInfo.ALGORITHM_ID, certificateAlgorithmId);
// 4. ะŸะพะดะฟะธัั‹ะฒะฐะตะผ ัะตั€ั‚ะธั„ะธะบะฐั‚
X509CertImpl certificate = new X509CertImpl(info);
certificate.sign(keyPair.getPrivate(), "SHA256withRSA");
// 5. ะŸั€ะพะฒะตั€ะบะฐ ัะตั€ั‚ะธั„ะธะบะฐั‚ะฐ
try {
	// ะ’ ัะปัƒั‡ะฐะต ะพัˆะธะฑะบะธ ะทะดะตััŒ ะฑัƒะดะตั‚ ะฑั€ะพัˆะตะฝะพ ะธัะบะปัŽั‡ะตะฝะธะต. ะะฐะฟั€ะธะผะตั€: java.security.SignatureException
	certificate.verify(keyPair.getPublic());
} catch (Exception e) {
	throw new IllegalStateException(e);
}
ืืจื›ื™ื˜ืงื˜ื•ืจืช ืงืจื™ืคื˜ื•ื’ืจืคื™ื” ืฉืœ Java: ื”ื™ื›ืจื•ืช ืจืืฉื•ื ื” - 15

Keystore (KeyStore)

ื”ื“ื‘ืจ ื”ืื—ืจื•ืŸ ืฉื”ื™ื™ืชื™ ืจื•ืฆื” ืœื“ื‘ืจ ืขืœื™ื• ื”ื•ื ื—ื ื•ืช ื”ืžืคืชื—ื•ืช ื•ื”ืชืขื•ื“ื•ืช, ืฉื ืงืจืืช KeyStore. ื‘ืจื•ืจ ืฉื”ืคืงื” ืžืชืžื“ืช ืฉืœ ืชืขื•ื“ื•ืช ื•ืžืคืชื—ื•ืช ื”ื™ื ื™ืงืจื” ื•ื—ืกืจืช ื˜ืขื. ืœื›ืŸ, ื”ื ืฆืจื™ื›ื™ื ืœื”ื™ื•ืช ืžืื•ื—ืกื ื™ื ืื™ื›ืฉื”ื• ื‘ื‘ื˜ื—ื”. ื™ืฉ ื›ืœื™ ืœื–ื” - KeyStore. ืžืื’ืจ ื”ืžืคืชื—ื•ืช ืžืชื•ืืจ ื‘ืชื™ืขื•ื“ JCA ื‘ืคืจืง " ื ื™ื”ื•ืœ ืžืคืชื—ื•ืช ". ื”-API ืœืขื‘ื•ื“ื” ืื™ืชื• ืžืื•ื“ ื‘ืจื•ืจ. ื”ื ื” ื“ื•ื’ืžื” ืงื˜ื ื”:
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
String alias = "EntityAlias";
java.security.cert.Certificate[] chain = {certificate};
keyStore.setKeyEntry(alias, keyPair.getPrivate(), "keyPassword".toCharArray(), chain);
// ะ—ะฐะณั€ัƒะทะบะฐ ัะพะดะตั€ะถะธะผะพะณะพ (Private Key + Certificate)
Key key = keyStore.getKey(alias, "keyPassword".toCharArray());
Certificate[] certificateChain = keyStore.getCertificateChain(alias);
// ะกะพั…ั€ะฐะฝะตะฝะธะต KeyStore ะฝะฐ ะดะธัะบ
File file = File.createTempFile("security_", ".ks");
System.out.println(file.getAbsolutePath());
try (FileOutputStream fos = new FileOutputStream(file)) {
	keyStore.store(fos, "keyStorePassword".toCharArray());
}
ื›ืคื™ ืฉื ื™ืชืŸ ืœืจืื•ืช ืžื”ื“ื•ื’ืžื”, ื”ื•ื ืžื‘ื•ืฆืข ืชื—ื™ืœื” loadืขื‘ื•ืจ ื”-KeyStore. ืื‘ืœ ื‘ืžืงืจื” ืฉืœื ื•, ืฆื™ื™ื ื• ืืช ื”ืชื›ื•ื ื” ื”ืจืืฉื•ื ื” ื›-null, ื›ืœื•ืžืจ. ืื™ืŸ ืžืงื•ืจ ืœ-KeyStore. ื”ืžืฉืžืขื•ืช ื”ื™ื ืฉื”-KeyStore ื ื•ืฆืจ ืจื™ืง ื›ื“ื™ ืœืฉืžื•ืจ ืื•ืชื• ืขื•ื“ ื™ื•ืชืจ. ื’ื ื”ืคืจืžื˜ืจ ื”ืฉื ื™ ื”ื•ื null, ื›ื™ ืื ื• ื™ื•ืฆืจื™ื ื—ื ื•ืช KeyStore ื—ื“ืฉื”. ืื ื”ื™ื™ื ื• ืžื˜ื™ืœื™ื ืืช KeyStore ืžืงื•ื‘ืฅ, ืื– ื”ื™ื™ื ื• ืฆืจื™ื›ื™ื ืœืฆื™ื™ืŸ ื›ืืŸ ืกื™ืกืžื” (ื‘ื“ื•ืžื” ืœืฉื™ื˜ืช KeyStore ืฉื ืงืจืืช store).

ืฉื•ืจื” ืชื—ืชื•ื ื”

ืื– ืกืงืจื ื• ืื™ืชืš ืืช ื”ืคืขื•ืœื•ืช ื”ื‘ืกื™ืกื™ื•ืช ื•ื”ื™ืกื•ื“ื™ื•ืช ื‘ื™ื•ืชืจ ื‘ืžืกื’ืจืช ืืจื›ื™ื˜ืงื˜ื•ืจืช ื”-Java Cryptography (aka JCA). ืจืื™ื ื• ืžื”ื™ ื”ืฆืคื ื” ืกื™ืžื˜ืจื™ืช ื•ืืกื™ืžื˜ืจื™ืช ื•ื›ื™ืฆื“ ื”ื™ื ืžื™ื•ืฉืžืช ื‘-JCA. ืจืื™ื ื• ื›ื™ืฆื“ ื ื•ืฆืจื™ื ืชืขื•ื“ื•ืช ื•ื—ืชื™ืžื•ืช ื“ื™ื’ื™ื˜ืœื™ื•ืช ื•ื›ื™ืฆื“ ืžืฉืชืžืฉื™ื ื‘ื”ืŸ. ื›ืœ ืืœื” ื”ื ืจืง ื”ื™ืกื•ื“ื•ืช, ืฉืžืื—ื•ืจื™ื”ื ื™ืฉ ื”ืจื‘ื” ื™ื•ืชืจ ื“ื‘ืจื™ื ืžื•ืจื›ื‘ื™ื ื•ืžืขื ื™ื™ื ื™ื. ืื ื™ ืžืงื•ื•ื” ืฉื—ื•ืžืจ ืกืงื™ืจื” ื–ื” ื™ื”ื™ื” ืฉื™ืžื•ืฉื™ ื•ื™ืขื ื™ื™ืŸ ืื•ืชืš ื‘ืœื™ืžื•ื“ ื ื•ืกืฃ ืฉืœ ืชื—ื•ื ื–ื”.
ื”ืขืจื•ืช
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION