Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

198
LINES

< > BotCompany Repo | #1001548 // PKI (Public Key Infrastructure, include)

JavaX fragment (include)

// TODO: Android N seems to deprecate SHA1PRNG
// https://android-developers.googleblog.com/2016/06/security-crypto-provider-deprecated-in.html

static class PKI {
  static String getProvider() {
    return isAndroid() ? /*"AndroidOpenSSL"*/ "BC" : "SUN";
  }
  
  public static boolean verifySignature(byte[] publicKey, byte[] signature, String file)
    throws InvalidKeyException, NoSuchProviderException, NoSuchAlgorithmException, IOException, SignatureException, InvalidKeySpecException {
    Signature sig = initPublicSignature(publicKey);

    FileInputStream datafis = new FileInputStream(file);
    BufferedInputStream bufin = new BufferedInputStream(datafis);

    byte[] buffer = new byte[1024];
    while (bufin.available() != 0) {
      int len = bufin.read(buffer);
      sig.update(buffer, 0, len);
    }

    bufin.close();

    return sig.verify(signature);
  }

  public static boolean verifySignature(byte[] publicKey, byte[] signature, byte[] data) ctex {
    Signature sig = initPublicSignature(publicKey);
    sig.update(data);
    return sig.verify(signature);
  }

  private static Signature initPublicSignature(byte[] publicKey) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, InvalidKeyException {
    Signature sig = Signature.getInstance("SHA1withDSA", getProvider());
    PublicKey pub = KeyFactory.getInstance("DSA", getProvider()).generatePublic(new X509EncodedKeySpec(publicKey));
    sig.initVerify(pub);
    return sig;
  }

  public static byte[] sign(String file, byte[] privateKey) ctex {
    Signature dsa = initSignature(privateKey);

    FileInputStream fis = new FileInputStream(file);
    BufferedInputStream bufin = new BufferedInputStream(fis);
    byte[] buffer = new byte[1024];
    int len;
    while ((len = bufin.read(buffer)) >= 0)
      dsa.update(buffer, 0, len);
    bufin.close();

    return dsa.sign();
  }

  public static byte[] sign(byte[] data, byte[] privateKey) ctex {
    Signature dsa = initSignature(privateKey);
    dsa.update(data);
    return dsa.sign();
  }

  private static Signature initSignature(byte[] privateKey) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, InvalidKeyException {
    Signature dsa = Signature.getInstance("SHA1withDSA", getProvider());
    //X509EncodedKeySpec keySpec = new X509EncodedKeySpec(privateKey);
    EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKey);
    PrivateKey priv = KeyFactory.getInstance("DSA", getProvider()).generatePrivate(keySpec);
    dsa.initSign(priv);
    return dsa;
  }

  public static KeyPair makeKeyPair() throws NoSuchAlgorithmException, NoSuchProviderException {
    KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA", getProvider());
    // OLD SecureRandom random = SecureRandom.getInstance("SHA1PRNG", getProvider());
    // should work on Android?
    SecureRandom random = SecureRandom.getInstance("SHA1PRNG");

    keyGen.initialize(1024, random);
    return keyGen.generateKeyPair();
  }

  // Standard key pair is for the MACHINE (not the user)
  public static boolean makeStandardKeyPairIfNecessary() ctex {
    File publicKeyPath = getStandardPublicKeyPath();
    File privateKeyPath = getStandardPrivateKeyPath();
    if (!publicKeyPath.exists() || !privateKeyPath.exists()) {
      print("PKI: Making standard key pair");
      KeyPair keyPair = makeKeyPair();
      byte[] privateKey = keyPair.getPrivate().getEncoded();
      print("PKI: Private key hex (debug) - " + bytesToHex(privateKey));
      saveTextFile(privateKeyPath, privateKeyToString(privateKey));
      String publicKey = publicKeyToString(keyPair.getPublic());
      saveTextFile(publicKeyPath, publicKey);
      print("PKI: Standard key pair made!");
      print();
      printInfo();
      return true;
    }
    return false;
  }
  
  static void printInfo() {
    print("PKI: Machine's public key: " + publicKeyToString(getStandardPublicKey()));
    print("PKI: Machine's private key in: " + getStandardPrivateKeyPath());
    print("PKI: Machine's public key also in: " + getStandardPublicKeyPath());
    print("PKI: User's public key: " + publicKeyToString(userPublicKey()));
    print("PKI: User's private key in: " + userPrivateKeyPath());
    print("PKI: User's public key also in: " + userPublicKeyPath());
  }

  public static File getStandardPrivateKeyPath() {
    return new File(getSecretProgramDir("#1001547"), "Computer-Private-Key");
  }

  public static File userPublicKeyPath() {
    return new File(getProgramDir("#1001547"), "User-Public-Key");
  }

  public static File userPrivateKeyPath() {
    return new File(getSecretProgramDir("#1001547"), "User-Private-Key");
  }

  public static File getStandardPublicKeyPath() {
    return new File(getProgramDir("#1001547"), "Computer-Public-Key");
  }

  public static byte[] getStandardPrivateKey() {
    makeStandardKeyPairIfNecessary();
    return privateKeyFromString(loadTextFile(getStandardPrivateKeyPath()));
  }

  public static byte[] getStandardPublicKey() {
    makeStandardKeyPairIfNecessary();
    return publicKeyFromString(loadTextFile(getStandardPublicKeyPath()));
  }

  public static byte[] userPrivateKey() {
    makeUserKeyPairIfNecessary();
    return privateKeyFromString(loadTextFile(userPrivateKeyPath()));
  }

  public static byte[] userPublicKey() {
    makeUserKeyPairIfNecessary();
    return publicKeyFromString(loadTextFile(userPublicKeyPath()));
  }

  private static String publicKeyToString(PublicKey publicKey) {
    return publicKeyToString(publicKey.getEncoded());
  }

  public static String privateKeyToString(PrivateKey privateKey) {
    return privateKeyToString(privateKey.getEncoded());
  }

  public static byte[] publicKeyFromString(String key) {
    return base64decode(dropPrefixMandatory("publickey:", trim(key)));
  }

  public static byte[] privateKeyFromString(String key) {
    return base64decode(dropPrefixMandatory("privatekey:", trim(key)));
  }

  public static byte[] signatureFromString(String key) {
    return base64decode(key);
  }

  public static byte[] dataFromString(String text) {
    return toUtf8(text);
  }

  public static String signatureToString(byte[] signature) {
    return base64encode(signature);
  }

  public static String publicKeyToString(byte[] key) {
    return "publickey:" + base64encode(key);
  }

  public static String privateKeyToString(byte[] key) {
    return "privatekey:" + base64encode(key);
  }
  
  static boolean makeUserKeyPairIfNecessary() ctex {
    File publicKeyPath = userPublicKeyPath();
    File privateKeyPath = userPrivateKeyPath();
    if (!publicKeyPath.exists() || !privateKeyPath.exists()) {
      print("PKI: Making user key pair");
      KeyPair keyPair = makeKeyPair();
      byte[] privateKey = keyPair.getPrivate().getEncoded();
      print("PKI: Private key hex (debug) - " + bytesToHex(privateKey));
      saveTextFile(privateKeyPath, privateKeyToString(privateKey));
      String publicKey = publicKeyToString(keyPair.getPublic());
      saveTextFile(publicKeyPath, publicKey);
      print("PKI: User key pair made!");
      print();
      printInfo();
      return true;
    }
    return false;
  }
}

download  show line numbers  debug dex  old transpilations   

Travelled to 17 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, jtubtzbbkimh, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, sawdedvomwva, tslmcundralx, tvejysmllsmz, vouqrxazstgt, whxojlpjdney, xrpafgyirdlv

No comments. add comment

Snippet ID: #1001548
Snippet name: PKI (Public Key Infrastructure, include)
Eternal ID of this version: #1001548/6
Text MD5: 10b11f88e89db899a4d9238fd9bda085
Author: stefan
Category: javax
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2020-07-17 13:29:16
Source code size: 7385 bytes / 198 lines
Pitched / IR pitched: No / No
Views / Downloads: 635 / 1776
Version history: 5 change(s)
Referenced in: [show references]