Ma tâche est la suivante:
output.dat
.Le programme ci-dessous génère une erreur: "Java.security.InvalidKeyException: aucun fournisseur installé ne prend en charge cette clé: Sun.security.provider.DSAPublicKeyImpl".
import Java.security.*;
import Java.security.KeyStore.*;
import Java.io.*;
import Java.security.PublicKey;
import Java.security.PrivateKey;
import javax.crypto.Cipher;
import Java.nio.charset.*;
import Sun.security.provider.*;
import javax.crypto.*;
public class Code {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
try {
/* getting data for keystore */
File file = new File(System.getProperty("user.home") + File.separatorChar + ".keystore");
FileInputStream is = new FileInputStream(file);
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
/*Information for certificate to be generated */
String password = "abcde";
String alias = "mykeys";
String alias1 = "skeys";
String filepath ="C:\\email.txt";
/* getting the key*/
keystore.load(is, password.toCharArray());
PrivateKey key = (PrivateKey)keystore.getKey(alias, "bemylife".toCharArray());
//PrivateKey key = cert1.getPrivateKey();
//PublicKey key1= (PrivateKey)key;
/* Get certificate of public key */
Java.security.cert.Certificate cert = keystore.getCertificate(alias);
/* Here it prints the public key*/
System.out.println("Public Key:");
System.out.println(cert.getPublicKey());
/* Here it prints the private key*/
System.out.println("\nPrivate Key:");
System.out.println(key);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE,cert.getPublicKey());
String cleartextFile = "C:\\email.txt";
String ciphertextFile = "D:\\ciphertextRSA.png";
FileInputStream fis = new FileInputStream(cleartextFile);
FileOutputStream fos = new FileOutputStream(ciphertextFile);
CipherOutputStream cos = new CipherOutputStream(fos, cipher);
byte[] block = new byte[32];
int i;
while ((i = fis.read(block)) != -1) {
cos.write(block, 0, i);
}
cos.close();
/* computing the signature*/
Signature dsa = Signature.getInstance("SHA1withDSA", "Sun");
dsa.initSign(key);
FileInputStream f = new FileInputStream(ciphertextFile);
BufferedInputStream in = new BufferedInputStream(f);
byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) >= 0) {
dsa.update(buffer, 0, len);
};
in.close();
/* Here it prints the signature*/
System.out.println("Digital Signature :");
System.out.println( dsa.sign());
/* Now Exporting Certificate */
System.out.println("Exporting Certificate. ");
byte[] buffer_out = cert.getEncoded();
FileOutputStream os = new FileOutputStream(new File("d:\\signedcetificate.cer"));
os.write(buffer_out);
os.close();
/* writing signature to output.dat file */
byte[] buffer_out1 = dsa.sign();
FileOutputStream os1 = new FileOutputStream(new File("d:\\output.dat"));
os1.write(buffer_out1);
os1.close();
} catch (Exception e) {System.out.println(e);}
}
}
Le problème est qu’une clé DSA ne convient pas au chiffrement RSA. Vous avez besoin d’une clé RSA pour le chiffrement. Vous pouvez peut-être basculer votre algorithme de signature sur RSA/SHA1 pour éviter le recours à deux clés.
Vous devez le lire à partir du fichier de clés (qui se termine probablement par .jks
) dans un objet Java.security.KeyStore .
/**
* Reads a Java keystore from a file.
*
* @param keystoreFile
* keystore file to read
* @param password
* password for the keystore file
* @param keyStoreType
* type of keystore, e.g., JKS or PKCS12
* @return the keystore object
* @throws KeyStoreException
* if the type of KeyStore could not be created
* @throws IOException
* if the keystore could not be loaded
* @throws NoSuchAlgorithmException
* if the algorithm used to check the integrity of the keystore
* cannot be found
* @throws CertificateException
* if any of the certificates in the keystore could not be loaded
*/
public static KeyStore loadKeyStore(final File keystoreFile,
final String password, final String keyStoreType)
throws KeyStoreException, IOException, NoSuchAlgorithmException,
CertificateException {
if (null == keystoreFile) {
throw new IllegalArgumentException("Keystore url may not be null");
}
LOG.debug("Initializing key store: {}", keystoreFile.getAbsolutePath());
final URI keystoreUri = keystoreFile.toURI();
final URL keystoreUrl = keystoreUri.toURL();
final KeyStore keystore = KeyStore.getInstance(keyStoreType);
InputStream is = null;
try {
is = keystoreUrl.openStream();
keystore.load(is, null == password ? null : password.toCharArray());
LOG.debug("Loaded key store");
} finally {
if (null != is) {
is.close();
}
}
return keystore;
}
Une fois que vous avez la KeyStore
, vous pouvez accéder à la Certificate
et aux clés publique et privée.
Mais utiliser cela pour signer du texte et le sauvegarder dans un fichier est plus compliqué et facile à faire mal. Examinez la chaîne Sign en utilisant la clé publique donnée et remplacez la méthode getKeyPair
par celle qui utilise la KeyStore
. Quelque chose dans le sens de
public static KeyPair getKeyPair(final KeyStore keystore,
final String alias, final String password) {
final Key key = (PrivateKey) keystore.getKey(alias, password.toCharArray());
final Certificate cert = keystore.getCertificate(alias);
final PublicKey publicKey = cert.getPublicKey();
return KeyPair(publicKey, (PrivateKey) key);
}
(évidemment un peu plus rugueux, je n'avais pas d'échantillon à portée de main)
Je n'ai pas le code Java stocké au sommet de mon cerveau, mais quelques vérifications générales sont:
le certificat public que vous souhaitez enregistrer est-il stocké où vous le souhaitez? En particulier, je me souviens que le certificat avec la clé publique et la clé privée sont stockés ensemble sous un seul alias. Le réglage de deux alias que vous avez défini semble donc très étrange. Essayez de stocker les deux sous le même alias et de le référencer dans les appels de clé privée et publique.
pouvez-vous obtenir autre chose du certificat - par exemple, le nom distinctif du sujet ou le nom distinctif de l'émetteur sont des champs obligatoires dans un certificat. Cela vous donne une bonne preuve que le certificat est lu comme prévu.
dans presque toutes les transactions cryptographiques, soyez très prudent avec la façon dont vous lisez les fichiers et transférez vos méthodes de codage. Si vous avez créé votre fichier IO et en avez extrait une étrange façon, vous pouvez corrompre le codage du matériel de clé. C'est une dernière chose à vérifier - généralement, Java et JKS n'ont pas été aussi mauvais pour cela, mais cela arrive. Dans le même esprit, précisez le format du fichier - les fichiers JKS sont différents des fichiers PKCS 12, par exemple.
trusted.load(in, ((PBCApplication) context.getApplicationContext()).getBuildSettings().getCertificatePass());
Enumeration enumeration = trusted.aliases();
while (enumeration.hasMoreElements()) {
String alias = (String) enumeration.nextElement();
System.out.println("alias name: " + alias);
Certificate certificate = trusted.getCertificate(alias);
certificate.getPublicKey();
}