Example usage for java.security KeyPairGenerator initialize

List of usage examples for java.security KeyPairGenerator initialize

Introduction

In this page you can find the example usage for java.security KeyPairGenerator initialize.

Prototype

public void initialize(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException 

Source Link

Document

Initializes the key pair generator using the specified parameter set and the SecureRandom implementation of the highest-priority installed provider as the source of randomness.

Usage

From source file:org.kuali.rice.ksb.security.admin.service.impl.JavaSecurityManagementServiceImpl.java

public KeyStore generateClientKeystore(String alias, String clientPassphrase) throws GeneralSecurityException {
    if (isAliasInKeystore(alias)) {
        throw new KeyStoreException("Alias '" + alias + "' already exists in module keystore");
    }//from   w w  w  .j a va2s  .  c  o m
    //        Certificate[] clientCertificateChain = {};
    //        PrivateKey clientPrivateKey = null;
    KeyStore ks = null;
    try {
        // generate a key pair for the client
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance(CLIENT_KEY_GENERATOR_ALGORITHM);
        //            SecureRandom random = SecureRandom.getInstance(CLIENT_SECURE_RANDOM_ALGORITHM);
        keyGen.initialize(CLIENT_KEY_PAIR_KEY_SIZE);
        //            keyGen.initialize(new RSAKeyGenParameterSpec(512,RSAKeyGenParameterSpec.F0));
        KeyPair pair = keyGen.generateKeyPair();

        //            PublicKey clientPublicKey = pair.getPublic();
        //            clientPrivateKey = pair.getPrivate();
        //            // generate the Certificate
        //            X509V3CertificateGenerator certificateGenerator = new X509V3CertificateGenerator();
        ////            X509Name nameInfo = new X509Name(false,"CN=" + alias);
        //            certificateGenerator.setSignatureAlgorithm("MD5WithRSA");
        //            certificateGenerator.setSerialNumber(new java.math.BigInteger("1"));
        //            X509Principal nameInfo = new X509Principal("CN=" + alias);
        //            certificateGenerator.setIssuerDN(nameInfo);
        //            certificateGenerator.setSubjectDN(nameInfo);                       // note: same as issuer
        //            certificateGenerator.setNotBefore(new Date());
        //            Calendar c = Calendar.getInstance();
        //            c.add(Calendar.DATE, CLIENT_CERT_EXPIRATION_DAYS);
        //            certificateGenerator.setNotAfter(c.getTime());
        //            certificateGenerator.setPublicKey(clientPublicKey);
        //            X509Certificate cert = certificateGenerator.generateX509Certificate(clientPrivateKey);
        //            clientCertificateChain = new Certificate[]{cert};
        //
        //            // generate client keyStore file
        //            ks = KeyStore.getInstance(getModuleKeyStoreType());
        //            ks.load(null, clientPassphrase.toCharArray());
        //            // set client private key on keyStore file
        //            ks.setEntry(alias, new KeyStore.PrivateKeyEntry(clientPrivateKey, clientCertificateChain), new KeyStore.PasswordProtection(clientPassphrase.toCharArray()));
        Certificate cert = generateCertificate(pair, alias);
        ks = generateKeyStore(cert, pair.getPrivate(), alias, clientPassphrase);

        // set the module certificate on the client keyStore file
        ks.setEntry(getModuleKeyStoreAlias(),
                new KeyStore.TrustedCertificateEntry(getCertificate(getModuleKeyStoreAlias())), null);

        // add the client certificate to the module keyStore
        addClientCertificateToModuleKeyStore(alias, cert);

        return ks;
    } catch (IOException e) {
        throw new RuntimeException("Could not create new KeyStore", e);
    }
}

From source file:org.dasein.cloud.test.identity.IdentityResources.java

/**
 * @link http://stackoverflow.com/a/14582408/211197
 * @return Encoded generated public key/*from   ww  w . j  a v a  2  s .  co  m*/
 */
private @Nullable String generateKey() {
    KeyPairGenerator generator;
    try {
        generator = KeyPairGenerator.getInstance("RSA");
        generator.initialize(2048);
        KeyPair keyPair = generator.genKeyPair();
        RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
        ByteArrayOutputStream byteOs = new ByteArrayOutputStream();
        DataOutputStream dos = new DataOutputStream(byteOs);
        dos.writeInt("ssh-rsa".getBytes().length);
        dos.write("ssh-rsa".getBytes());
        dos.writeInt(rsaPublicKey.getPublicExponent().toByteArray().length);
        dos.write(rsaPublicKey.getPublicExponent().toByteArray());
        dos.writeInt(rsaPublicKey.getModulus().toByteArray().length);
        dos.write(rsaPublicKey.getModulus().toByteArray());
        String publicKeyEncoded = new String(Base64.encodeBase64(byteOs.toByteArray()));
        return "ssh-rsa " + publicKeyEncoded + " dasein";
    } catch (Throwable e) {
        return null;
    }
}

From source file:org.apache.hadoop.yarn.server.resourcemanager.security.TestHopsworksRMAppSecurityActions.java

private PKCS10CertificationRequest generateCSR(String cn) throws Exception {
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA", "BC");
    keyPairGenerator.initialize(1024);
    KeyPair keyPair = keyPairGenerator.genKeyPair();

    X500NameBuilder x500NameBuilder = new X500NameBuilder(BCStyle.INSTANCE);
    x500NameBuilder.addRDN(BCStyle.CN, cn);
    x500NameBuilder.addRDN(BCStyle.O, O);
    x500NameBuilder.addRDN(BCStyle.OU, OU);
    X500Name x500Name = x500NameBuilder.build();

    PKCS10CertificationRequestBuilder csrBuilder = new JcaPKCS10CertificationRequestBuilder(x500Name,
            keyPair.getPublic());//w w  w  . ja  v a2s.c o m
    return csrBuilder
            .build(new JcaContentSignerBuilder("SHA256withRSA").setProvider("BC").build(keyPair.getPrivate()));
}

From source file:org.apache.openaz.xacml.pdp.test.custom.TestCustom.java

/**
 * This function generates the public/private key pair. Should never have to call this again, this was
 * called once to generate the keys. They were saved into the testsets/custom/datatype-function
 * sub-directory.//from  w w w. j a va  2 s . c  o m
 */
public void generateKeyPair() {
    //
    // Generate a RSA private/public key pair
    //
    KeyPairGenerator keyGen;
    try {
        keyGen = KeyPairGenerator.getInstance(ALGORITHM);
    } catch (NoSuchAlgorithmException e) {
        logger.error("failed to generate keypair: " + e);
        return;
    }
    keyGen.initialize(1024);
    final KeyPair key = keyGen.generateKeyPair();
    //
    // Save the keys to disk
    //
    Path file = Paths.get(this.directory, PRIVATEKEY_FILE);
    try (ObjectOutputStream os = new ObjectOutputStream(Files.newOutputStream(file))) {
        os.writeObject(key.getPrivate());
    } catch (IOException e) {
        e.printStackTrace();
    }
    file = Paths.get(this.directory, PUBLICKEY_FILE);
    try (ObjectOutputStream os = new ObjectOutputStream(Files.newOutputStream(file))) {
        os.writeObject(key.getPublic());
    } catch (IOException e) {
        e.printStackTrace();
    }
}

From source file:org.asimba.wa.integrationtest.saml2.model.AuthnRequest.java

public String getSignedRequest(int format, InputStream keystoreStream, String keystorePassword, String keyAlias,
        String keyPassword) {/*from w  ww.j av a 2  s .c  om*/
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setNamespaceAware(true);

    DocumentBuilder builder;
    Document doc;
    try {
        builder = dbf.newDocumentBuilder();
        doc = builder.parse(new InputSource(new ByteArrayInputStream(getRequest(plain).getBytes("utf-8"))));

        // Prepare doc by marking attributes as referenceable:
        tagIdAttributes(doc);

        // Prepare cryptographic environemnt
        KeyStore keystore = getKeystore("JKS", keystoreStream, keystorePassword);
        if (keystore == null)
            return null;

        KeyPair kp;

        kp = getKeyPairFromKeystore(keystore, keyAlias, keyPassword);
        if (kp == null) {
            // Generate key, to prove that it works...
            KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA");
            kpg.initialize(512);
            kp = kpg.generateKeyPair();
        }

        // Set signing context with PrivateKey and root of the Document
        DOMSignContext dsc = new DOMSignContext(kp.getPrivate(), doc.getDocumentElement());

        // Get SignatureFactory for creating signatures in DOM:
        XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");

        // Create reference for "" -> root of the document
        // SAML requires enveloped transform
        Reference ref = fac.newReference("#" + this._id, fac.newDigestMethod(DigestMethod.SHA1, null),
                Collections.singletonList(fac.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null)),
                null, null);

        // Create SignedInfo (SAML2: Exclusive with or without comments is specified)
        SignedInfo si = fac.newSignedInfo(
                fac.newCanonicalizationMethod(CanonicalizationMethod.EXCLUSIVE_WITH_COMMENTS,
                        (C14NMethodParameterSpec) null),
                fac.newSignatureMethod(SignatureMethod.DSA_SHA1, null), Collections.singletonList(ref));

        // Add KeyInfo to the document:
        KeyInfoFactory kif = fac.getKeyInfoFactory();

        // .. get key from the generated keypair:
        KeyValue kv = kif.newKeyValue(kp.getPublic());
        KeyInfo ki = kif.newKeyInfo(Collections.singletonList(kv));

        XMLSignature signature = fac.newXMLSignature(si, ki);

        String before = docToString(doc);

        // Sign!
        signature.sign(dsc);

        _authnRequestDocument = doc; // persist, as we've worked hard for it

        String after = docToString(doc);

        if (_logger.isDebugEnabled()) {
            _logger.debug("Before: {}", before);
            _logger.debug("After : {}", after);
        }

        return after;

    } catch (ParserConfigurationException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (SAXException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (XMLStreamException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        // key generation exception
        e.printStackTrace();
    } catch (InvalidAlgorithmParameterException e) {
        // digest algorithm selection exception
        e.printStackTrace();
    } catch (KeyException e) {
        // when key-value was not available (when adding to KeyInfo)
        e.printStackTrace();
    } catch (MarshalException e) {
        // sign didn't work:
        e.printStackTrace();
    } catch (XMLSignatureException e) {
        // sign didn't work:
        e.printStackTrace();
    }
    return null;
}

From source file:nl.afas.cordova.plugin.secureLocalStorage.SecureLocalStorage.java

@TargetApi(18)
private KeyStore initKeyStore() throws SecureLocalStorageException {
    try {/*from w  w  w . ja  v  a  2s.  com*/
        KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
        keyStore.load(null);

        if (!keyStore.containsAlias(SECURELOCALSTORAGEALIAS)) {

            Calendar start = Calendar.getInstance();
            Calendar end = Calendar.getInstance();
            end.add(Calendar.YEAR, 3);

            KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(_cordova.getActivity())
                    .setAlias(SECURELOCALSTORAGEALIAS)
                    .setSubject(new X500Principal(String.format("CN=%s, O=%s", "SecureLocalStorage",
                            _cordova.getActivity().getBaseContext().getPackageName())))
                    .setSerialNumber(BigInteger.ONE).setStartDate(start.getTime()).setEndDate(end.getTime())
                    .build();
            KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
            generator.initialize(spec);

            generator.generateKeyPair();
        }

        return keyStore;
    } catch (Exception e) {
        throw new SecureLocalStorageException("Could not initialize keyStore", e);
    }
}

From source file:netinf.common.security.identity.impl.IdentityManagerImpl.java

/**
 * @see IdentityManager#createNewMasterIdentity()
 *///from   w ww  .j a v a 2s .  c  o m
@Override
public IdentityObject createNewMasterIdentity() throws NetInfCheckedException {
    // as soon as a new Master Identity is created, all Identites known to this IdentityManager will be stored to file. Thus,
    // ensure that identities are loaded from file before
    if (this.privateKeys.size() == 0) {
        try {
            loadIdentities();
        } catch (NetInfCheckedException e) {
            LOG.warn("Unable to load key file. " + e.getMessage());
        }
    }

    KeyPairGenerator k;
    try {
        k = KeyPairGenerator.getInstance("RSA");

    } catch (Exception e) {
        LOG.warn(e.getMessage());
        return null;
    }

    k.initialize(1024);
    KeyPair pair = k.generateKeyPair();

    // A new Master Identity implies a new Identity Object. Create it
    IdentityObject newIdentity = ValidCreator.createValidIdentityObject(pair.getPublic());

    // Derive the "Identity-Path"
    String pathToKey = newIdentity.getIdentifier().toString() + IntegrityImpl.PATH_SEPERATOR
            + DefinedAttributeIdentification.PUBLIC_KEY.getURI();

    this.privateKeys.put(pathToKey, pair.getPrivate());

    LOG.info("Private Key: " + Utils.objectToString(pair.getPrivate()));
    LOG.info("Public Key: " + Utils.objectToString(pair.getPublic()));

    // save private keys to file
    writePrivateKeysToFile(this.defaultFilepath, this.defaultKeyAlgorithmName, this.defaultPassword);

    return newIdentity;
}

From source file:com.qut.middleware.crypto.impl.CryptoProcessorImpl.java

public KeyPair generateKeyPair() throws CryptoException {
    try {/*  w w w .j a  v a  2 s.  c  om*/
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        keyGen.initialize(this.keySize);

        KeyPair keyPair = keyGen.generateKeyPair();
        return keyPair;
    } catch (NoSuchAlgorithmException e) {
        this.logger.error("NoSuchAlgorithmException thrown, " + e.getLocalizedMessage());
        this.logger.debug(e.toString());
        throw new CryptoException(e.getLocalizedMessage(), e);
    }
}

From source file:org.loklak.api.aaa.PublicKeyRegistrationService.java

@Override
public JSONObject serviceImpl(Query post, HttpServletResponse response, Authorization authorization,
        final JSONObjectWithDefault permissions) throws APIException {

    if (post.get("register", null) == null && !post.get("create", false) && !post.get("getParameters", false)) {
        throw new APIException(400, "Accepted parameters: 'register', 'create' or 'getParameters'");
    }//from  ww  w . j a v a  2 s  .c om

    JSONObject result = new JSONObject();

    // return algorithm parameters and users for whom we are allowed to register a key
    if (post.get("getParameters", false)) {
        result.put("self", permissions.getBoolean("self", false));
        result.put("users", permissions.getJSONObject("users"));
        result.put("userRoles", permissions.getJSONObject("userRoles"));

        JSONObject algorithms = new JSONObject();

        JSONObject rsa = new JSONObject();
        JSONArray keySizes = new JSONArray();
        for (int i : allowedKeySizesRSA) {
            keySizes.put(i);
        }
        rsa.put("sizes", keySizes);
        rsa.put("defaultSize", defaultKeySizeRSA);
        algorithms.put("RSA", rsa);
        result.put("algorithms", algorithms);

        JSONArray formats = new JSONArray();
        for (String format : allowedFormats) {
            formats.put(format);
        }
        result.put("formats", formats);

        return result;
    }

    // for which id?
    String id;
    if (post.get("id", null) != null)
        id = post.get("id", null);
    else
        id = authorization.getIdentity().getName();

    // check if we are allowed register a key
    if (!id.equals(authorization.getIdentity().getName())) { // if we don't want to register the key for the current user

        // create Authentication to check if the user id is a registered user
        ClientCredential credential = new ClientCredential(ClientCredential.Type.passwd_login, id);
        Authentication authentication = new Authentication(credential, DAO.authentication);

        if (authentication.getIdentity() == null) { // check if identity is valid
            authentication.delete();
            throw new APIException(400, "Bad request"); // do not leak if user exists or not
        }

        // check if the current user is allowed to create a key for the user in question
        boolean allowed = false;
        // check if the user in question is in 'users'
        if (permissions.getJSONObject("users", null).has(id)
                && permissions.getJSONObjectWithDefault("users", null).getBoolean(id, false)) {
            allowed = true;
        } else { // check if the user role of the user in question is in 'userRoles'
            Authorization auth = new Authorization(authentication.getIdentity(), DAO.authorization,
                    DAO.userRoles);
            for (String key : permissions.getJSONObject("userRoles").keySet()) {
                if (key.equals(auth.getUserRole().getName())
                        && permissions.getJSONObject("userRoles").getBoolean(key)) {
                    allowed = true;
                }
            }
        }
        if (!allowed)
            throw new APIException(400, "Bad request"); // do not leak if user exists or not
    } else { // if we want to register a key for this user, bad are not allowed to (for example anonymous users)
        if (!permissions.getBoolean("self", false))
            throw new APIException(403, "You are not allowed to register a public key");
    }

    // set algorithm. later, we maybe want to support other algorithms as well
    String algorithm = "RSA";
    if (post.get("algorithm", null) != null) {
        algorithm = post.get("algorithm", null);
    }

    if (post.get("create", false)) { // create a new key pair on the server

        if (algorithm.equals("RSA")) {
            int keySize = 2048;
            if (post.get("key-size", null) != null) {
                int finalKeyLength = post.get("key-size", 0);
                if (!IntStream.of(allowedKeySizesRSA).anyMatch(x -> x == finalKeyLength)) {
                    throw new APIException(400, "Invalid key size.");
                }
                keySize = finalKeyLength;
            }

            KeyPairGenerator keyGen;
            KeyPair keyPair;
            try {
                keyGen = KeyPairGenerator.getInstance(algorithm);
                keyGen.initialize(keySize);
                keyPair = keyGen.genKeyPair();
            } catch (NoSuchAlgorithmException e) {
                throw new APIException(500, "Server error");
            }

            registerKey(authorization.getIdentity(), keyPair.getPublic());

            String pubkey_pem = null, privkey_pem = null;
            try {
                StringWriter writer = new StringWriter();
                PemWriter pemWriter = new PemWriter(writer);
                pemWriter.writeObject(new PemObject("PUBLIC KEY", keyPair.getPublic().getEncoded()));
                pemWriter.flush();
                pemWriter.close();
                pubkey_pem = writer.toString();
            } catch (IOException e) {
            }
            try {
                StringWriter writer = new StringWriter();
                PemWriter pemWriter = new PemWriter(writer);
                pemWriter.writeObject(new PemObject("PRIVATE KEY", keyPair.getPrivate().getEncoded()));
                pemWriter.flush();
                pemWriter.close();
                privkey_pem = writer.toString();
            } catch (IOException e) {
            }

            result.put("publickey_DER_BASE64",
                    Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded()));
            result.put("privatekey_DER_BASE64",
                    Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded()));
            result.put("publickey_PEM", pubkey_pem);
            result.put("privatekey_PEM", privkey_pem);
            result.put("keyhash", IO.getKeyHash(keyPair.getPublic()));
            try {
                result.put("keyhash_urlsave", URLEncoder.encode(IO.getKeyHash(keyPair.getPublic()), "UTF-8"));
            } catch (UnsupportedEncodingException e) {
            }
            result.put("key-size", keySize);
            result.put("message",
                    "Successfully created and registered key. Make sure to copy the private key, it won't be saved on the server");

            return result;
        }
        throw new APIException(400, "Unsupported algorithm");
    } else if (post.get("register", null) != null) {

        if (algorithm.equals("RSA")) {
            String type = post.get("type", null);
            if (type == null)
                type = "DER";

            RSAPublicKey pub;
            String encodedKey;
            try {
                encodedKey = URLDecoder.decode(post.get("register", null), "UTF-8");
            } catch (Throwable e) {
                throw new APIException(500, "Server error");
            }
            Log.getLog().info("Key (" + type + "): " + encodedKey);

            if (type.equals("DER")) {
                try {
                    X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(encodedKey));
                    pub = (RSAPublicKey) KeyFactory.getInstance(algorithm).generatePublic(keySpec);
                } catch (Throwable e) {
                    throw new APIException(400, "Public key not readable (DER)");
                }
            } else if (type.equals("PEM")) {
                try {
                    PemReader pemReader = new PemReader(new StringReader(encodedKey));
                    PemObject pem = pemReader.readPemObject();
                    X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pem.getContent());
                    pub = (RSAPublicKey) KeyFactory.getInstance(algorithm).generatePublic(keySpec);
                } catch (Exception e) {
                    throw new APIException(400, "Public key not readable (PEM)");
                }
            } else {
                throw new APIException(400, "Invalid value for 'type'.");
            }

            // check key size (not really perfect yet)
            int keySize;
            int bitLength = pub.getModulus().bitLength();
            if (bitLength <= 512) {
                keySize = 512;
            } else if (bitLength <= 1024) {
                keySize = 1024;
            } else if (bitLength <= 2048) {
                keySize = 2048;
            } else if (bitLength <= 4096) {
                keySize = 4096;
            } else {
                keySize = 8192;
            }
            if (!IntStream.of(allowedKeySizesRSA).anyMatch(x -> x == keySize)) {
                throw new APIException(400, "Invalid key length.");
            }

            registerKey(authorization.getIdentity(), pub);

            String pubkey_pem = null;
            try {
                StringWriter writer = new StringWriter();
                PemWriter pemWriter = new PemWriter(writer);
                pemWriter.writeObject(new PemObject("PUBLIC KEY", pub.getEncoded()));
                pemWriter.flush();
                pemWriter.close();
                pubkey_pem = writer.toString();
            } catch (IOException e) {
            }

            result.put("publickey_DER_BASE64", Base64.getEncoder().encodeToString(pub.getEncoded()));
            result.put("publickey_PEM", pubkey_pem);
            result.put("keyhash", IO.getKeyHash(pub));
            try {
                result.put("keyhash_urlsave", URLEncoder.encode(IO.getKeyHash(pub), "UTF-8"));
            } catch (UnsupportedEncodingException e) {
            }
            result.put("message", "Successfully registered key.");

            return result;
        }
        throw new APIException(400, "Unsupported algorithm");
    }

    throw new APIException(400, "Invalid parameter");
}

From source file:ai.susi.server.api.aaa.PublicKeyRegistrationService.java

@Override
public JSONObject serviceImpl(Query post, HttpServletResponse response, Authorization authorization,
        final JsonObjectWithDefault permissions) throws APIException {

    if (post.get("register", null) == null && !post.get("create", false) && !post.get("getParameters", false)) {
        throw new APIException(400, "Accepted parameters: 'register', 'create' or 'getParameters'");
    }// w ww . j a v  a  2  s.c  om

    JSONObject result = new JSONObject();

    // return algorithm parameters and users for whom we are allowed to register a key
    if (post.get("getParameters", false)) {
        result.put("self", permissions.getBoolean("self", false));
        result.put("users", permissions.getJSONObject("users"));
        result.put("userRoles", permissions.getJSONObject("userRoles"));

        JSONObject algorithms = new JSONObject();

        JSONObject rsa = new JSONObject();
        JSONArray keySizes = new JSONArray();
        for (int i : allowedKeySizesRSA) {
            keySizes.put(i);
        }
        rsa.put("sizes", keySizes);
        rsa.put("defaultSize", defaultKeySizeRSA);
        algorithms.put("RSA", rsa);
        result.put("algorithms", algorithms);

        JSONArray formats = new JSONArray();
        for (String format : allowedFormats) {
            formats.put(format);
        }
        result.put("formats", formats);

        return result;
    }

    // for which id?
    String id;
    if (post.get("id", null) != null)
        id = post.get("id", null);
    else
        id = authorization.getIdentity().getName();

    // check if we are allowed register a key
    if (!id.equals(authorization.getIdentity().getName())) { // if we don't want to register the key for the current user

        // create Authentication to check if the user id is a registered user
        ClientCredential credential = new ClientCredential(ClientCredential.Type.passwd_login, id);
        Authentication authentication = new Authentication(credential, DAO.authentication);

        if (authentication.getIdentity() == null) { // check if identity is valid
            authentication.delete();
            throw new APIException(400, "Bad request"); // do not leak if user exists or not
        }

        // check if the current user is allowed to create a key for the user in question
        boolean allowed = false;
        // check if the user in question is in 'users'
        if (permissions.getJSONObject("users", null).has(id)
                && permissions.getJSONObjectWithDefault("users", null).getBoolean(id, false)) {
            allowed = true;
        } else { // check if the user role of the user in question is in 'userRoles'
            Authorization auth = new Authorization(authentication.getIdentity(), DAO.authorization,
                    DAO.userRoles);
            for (String key : permissions.getJSONObject("userRoles").keySet()) {
                if (key.equals(auth.getUserRole().getName())
                        && permissions.getJSONObject("userRoles").getBoolean(key)) {
                    allowed = true;
                }
            }
        }
        if (!allowed)
            throw new APIException(400, "Bad request"); // do not leak if user exists or not
    } else { // if we want to register a key for this user, bad are not allowed to (for example anonymous users)
        if (!permissions.getBoolean("self", false))
            throw new APIException(403, "You are not allowed to register a public key");
    }

    // set algorithm. later, we maybe want to support other algorithms as well
    String algorithm = "RSA";
    if (post.get("algorithm", null) != null) {
        algorithm = post.get("algorithm", null);
    }

    if (post.get("create", false)) { // create a new key pair on the server

        if (algorithm.equals("RSA")) {
            int keySize = 2048;
            if (post.get("key-size", null) != null) {
                int finalKeyLength = post.get("key-size", 0);
                if (!IntStream.of(allowedKeySizesRSA).anyMatch(x -> x == finalKeyLength)) {
                    throw new APIException(400, "Invalid key size.");
                }
                keySize = finalKeyLength;
            }

            KeyPairGenerator keyGen;
            KeyPair keyPair;
            try {
                keyGen = KeyPairGenerator.getInstance(algorithm);
                keyGen.initialize(keySize);
                keyPair = keyGen.genKeyPair();
            } catch (NoSuchAlgorithmException e) {
                throw new APIException(500, "Server error");
            }

            registerKey(authorization.getIdentity(), keyPair.getPublic());

            String pubkey_pem = null, privkey_pem = null;
            try {
                StringWriter writer = new StringWriter();
                PemWriter pemWriter = new PemWriter(writer);
                pemWriter.writeObject(new PemObject("PUBLIC KEY", keyPair.getPublic().getEncoded()));
                pemWriter.flush();
                pemWriter.close();
                pubkey_pem = writer.toString();
            } catch (IOException e) {
            }
            try {
                StringWriter writer = new StringWriter();
                PemWriter pemWriter = new PemWriter(writer);
                pemWriter.writeObject(new PemObject("PRIVATE KEY", keyPair.getPrivate().getEncoded()));
                pemWriter.flush();
                pemWriter.close();
                privkey_pem = writer.toString();
            } catch (IOException e) {
            }

            result.put("publickey_DER_BASE64",
                    Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded()));
            result.put("privatekey_DER_BASE64",
                    Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded()));
            result.put("publickey_PEM", pubkey_pem);
            result.put("privatekey_PEM", privkey_pem);
            result.put("keyhash", IO.getKeyHash(keyPair.getPublic()));
            try {
                result.put("keyhash_urlsave", URLEncoder.encode(IO.getKeyHash(keyPair.getPublic()), "UTF-8"));
            } catch (UnsupportedEncodingException e) {
            }
            result.put("key-size", keySize);
            result.put("message",
                    "Successfully created and registered key. Make sure to copy the private key, it won't be saved on the server");

            return result;
        }
        throw new APIException(400, "Unsupported algorithm");
    } else if (post.get("register", null) != null) {

        if (algorithm.equals("RSA")) {
            String type = post.get("type", null);
            if (type == null)
                type = "DER";

            RSAPublicKey pub;
            String encodedKey;
            try {
                encodedKey = URLDecoder.decode(post.get("register", null), "UTF-8");
            } catch (Throwable e) {
                throw new APIException(500, "Server error");
            }
            Log.getLog().info("Key (" + type + "): " + encodedKey);

            if (type.equals("DER")) {
                try {
                    X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(encodedKey));
                    pub = (RSAPublicKey) KeyFactory.getInstance(algorithm).generatePublic(keySpec);
                } catch (Throwable e) {
                    throw new APIException(400, "Public key not readable (DER)");
                }
            } else if (type.equals("PEM")) {
                try {
                    PemReader pemReader = new PemReader(new StringReader(encodedKey));
                    PemObject pem = pemReader.readPemObject();
                    X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pem.getContent());
                    pub = (RSAPublicKey) KeyFactory.getInstance(algorithm).generatePublic(keySpec);
                } catch (Exception e) {
                    throw new APIException(400, "Public key not readable (PEM)");
                }
            } else {
                throw new APIException(400, "Invalid value for 'type'.");
            }

            // check key size (not really perfect yet)
            int keySize;
            int bitLength = pub.getModulus().bitLength();
            if (bitLength <= 512) {
                keySize = 512;
            } else if (bitLength <= 1024) {
                keySize = 1024;
            } else if (bitLength <= 2048) {
                keySize = 2048;
            } else if (bitLength <= 4096) {
                keySize = 4096;
            } else {
                keySize = 8192;
            }
            if (!IntStream.of(allowedKeySizesRSA).anyMatch(x -> x == keySize)) {
                throw new APIException(400, "Invalid key length.");
            }

            registerKey(authorization.getIdentity(), pub);

            String pubkey_pem = null;
            try {
                StringWriter writer = new StringWriter();
                PemWriter pemWriter = new PemWriter(writer);
                pemWriter.writeObject(new PemObject("PUBLIC KEY", pub.getEncoded()));
                pemWriter.flush();
                pemWriter.close();
                pubkey_pem = writer.toString();
            } catch (IOException e) {
            }

            result.put("publickey_DER_BASE64", Base64.getEncoder().encodeToString(pub.getEncoded()));
            result.put("publickey_PEM", pubkey_pem);
            result.put("keyhash", IO.getKeyHash(pub));
            try {
                result.put("keyhash_urlsave", URLEncoder.encode(IO.getKeyHash(pub), "UTF-8"));
            } catch (UnsupportedEncodingException e) {
            }
            result.put("message", "Successfully registered key.");

            return result;
        }
        throw new APIException(400, "Unsupported algorithm");
    }

    throw new APIException(400, "Invalid parameter");
}