Chiffrer mail avec SMIME et X. 509 à l'aide de BouncyCastle
Je suis en train d'envoyer un message crypté avec JavaMail
Bibliothèque et BouncyCastle
Bibliothèque:
C'est le code que j'ai écrit, ou j'ai suivi un tutoriel:
public class SendMail extends javax.mail.Authenticator {
private String _user;
private String _pass;
private String[] _to;
private String _from;
private String _port;
private String _sport;
private String _host;
private String _subject;
private String _body;
private boolean _auth;
private boolean _debuggable;
private Multipart _multipart;
SharedPreferences sharedPrefs;
InputStream privateKeyStoreInputStream;
InputStream publicCertificateInputStream;
InputStream publicKeystoreInputStream;
public static final String ksPassword = "mobile";
Certificate[] chain;
PrivateKey privateKey;
Certificate rcptCert;
CertificateFactory cf;
public SendMail() {
_user = ""; //username
_pass = ""; //password
_from = ""; //email sent from
_subject = ""; //email subject
_body = ""; //email body
_debuggable = false; //debug mode on or off - default off
_auth = true; //smtp authentication - default on
_multipart = new MimeMultipart();
//There is something wrong with MailCap, javamail can not find a
//handler for the multipart/mixed part, so this bit needs to be added.
MailcapCommandMap mc = (MailcapCommandMap) CommandMap
.getDefaultCommandMap();
mc.addMailcap("application/pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_signature");
mc.addMailcap("application/pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_mime");
mc.addMailcap("application/x-pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_signature");
mc.addMailcap("application/x-pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_mime");
mc.addMailcap("multipart/signed;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.multipart_signed");
CommandMap.setDefaultCommandMap(mc);
Security.addProvider(new BouncyCastleProvider());
}
public SendMail(Context c, InputStream privateKeyStoreInputStream,
InputStream publicCertificateInputStream,
InputStream publicKeystoreInputStream) {
this();
this.privateKeyStoreInputStream = privateKeyStoreInputStream;
this.publicCertificateInputStream = publicCertificateInputStream;
this.publicKeystoreInputStream = publicKeystoreInputStream;
_host = "removed";
_port = "25";
_sport = "25";
_user = "removed";
_pass = "removed";
try {
KeyStore keystore = KeyStore.getInstance("PKCS12", "BC");
keystore.load(privateKeyStoreInputStream, ksPassword.toCharArray());
Enumeration e = keystore.aliases();
String keyAlias = null;
while (e.hasMoreElements() && (keyAlias == null)) {
String alias = (String) e.nextElement();
keyAlias = keystore.isKeyEntry(alias) ? alias : null;
}
if (keyAlias == null) {
Log.e("KEY ALIAS: ", "NULL");
return;
}
chain = keystore.getCertificateChain(keyAlias);
/* Get the private key to sign the message */
privateKey = (PrivateKey) keystore.getKey(keyAlias,
ksPassword.toCharArray());
if (privateKey == null) {
Log.e("No Private key for: ", keyAlias);
}
/* Get the public key of reciepient */
BufferedInputStream bis = new BufferedInputStream(
publicCertificateInputStream);
cf = CertificateFactory.getInstance("X.509");
rcptCert = cf.generateCertificate(bis);
} catch (KeyStoreException e) {
Log.e("KeyStore Exception: ", e.getMessage());
} catch (NoSuchProviderException e) {
Log.e("NoSuchProvider Exception: ", e.getMessage());
} catch (CertificateException ce) {
Log.e("Certification Exception: ", ce.getMessage());
} catch (NoSuchAlgorithmException ns) {
Log.e("NoSuchAlgorithm Exception: ", ns.getMessage());
} catch (IOException e) {
Log.e("IO Exception: ", e.getMessage());
} catch (UnrecoverableKeyException uke) {
Log.e("UnrecoverableKeyException: ", uke.getMessage());
}
}
public boolean send() throws Exception {
Properties props = _setProperties();
if (!_user.equals("") && !_pass.equals("") && _to.length > 0
&& !_from.equals("") && !_subject.equals("")
&& !_body.equals("")) {
Session session = Session.getInstance(props,
new GMailAuthenticator(_user, _pass));
MimeMessage msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(_from));
InternetAddress[] addressTo = new InternetAddress[_to.length];
for (int i = 0; i < _to.length; i++) {
addressTo[i] = new InternetAddress(_to[i]);
}
msg.setRecipients(MimeMessage.RecipientType.TO, addressTo);
msg.setSubject(_subject);
msg.setSentDate(new Date());
//setup message body
BodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setText(_body);
_multipart.addBodyPart(messageBodyPart);
//Put parts in message
msg.setContent(_multipart);
/* Create SMIMESignedGenerator */
SMIMECapabilityVector capabilities = new SMIMECapabilityVector();
capabilities.addCapability(SMIMECapability.dES_EDE3_CBC);
capabilities.addCapability(SMIMECapability.rC2_CBC, 128);
capabilities.addCapability(SMIMECapability.dES_CBC);
ASN1EncodableVector attributes = new ASN1EncodableVector();
//attributes.add(new SMIMEEncryptionKeyPreferenceAttribute(new
//org.bouncycastle.asn1.cms.IssuerAndSerialNumber(new
//X509Name(((X509Certificate)chain[0]).getIssuerDN().getName()),
//((X509Certificate)chain[0]).getSerialNumber())));
attributes.add(new SMIMECapabilitiesAttribute(capabilities));
SMIMESignedGenerator signer = new SMIMESignedGenerator();
signer.addSigner(
privateKey,
(X509Certificate) chain[0],
"DSA".equals(privateKey.getAlgorithm()) ? SMIMESignedGenerator.DIGEST_SHA1
: SMIMESignedGenerator.DIGEST_MD5,
new AttributeTable(attributes), null);
/* Add the list of certs to the generator */
List certList = new ArrayList();
certList.add(chain[0]);
CertStore certs = CertStore.getInstance("Collection",
new CollectionCertStoreParameters(certList), "BC");
signer.addCertificatesAndCRLs(certs);
/* Sign the message and copy all headers from original message */
MimeMultipart multipart = signer.generate(msg, "BC");
MimeMessage signedMessage = new MimeMessage(session);
Enumeration headers = msg.getAllHeaderLines();
while (headers.hasMoreElements()) {
signedMessage.addHeaderLine((String) headers.nextElement());
}
signedMessage.setContent(_multipart);
signedMessage.saveChanges();
/* Create the encrypter and encrypt the message */
SMIMEEnvelopedGenerator encrypter = new SMIMEEnvelopedGenerator();
encrypter.addKeyTransRecipient((X509Certificate) chain[0]);
encrypter.addKeyTransRecipient((X509Certificate) rcptCert);
MimeBodyPart encryptedPart = encrypter.generate(signedMessage,
SMIMEEnvelopedGenerator.RC2_CBC, 128, "BC");
ByteArrayOutputStream out = new ByteArrayOutputStream();
encryptedPart.writeTo(out);
Session smtpSession = Session.getInstance(props, null);
MimeMessage smtpMessage = new MimeMessage(smtpSession,
new ByteArrayInputStream(out.toByteArray()));
smtpMessage.saveChanges();
Transport.send(smtpMessage);
return true;
} else {
return false;
}
}
public void addAttachment(String filename) throws Exception {
BodyPart messageBodyPart = new MimeBodyPart();
DataSource source = new FileDataSource(filename);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(filename);
_multipart.addBodyPart(messageBodyPart);
}
class GMailAuthenticator extends Authenticator {
String user;
String pw;
public GMailAuthenticator(String username, String password) {
super();
this.user = username;
this.pw = password;
}
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(user, pw);
}
}
private Properties _setProperties() {
Properties props = new Properties();
props.put("mail.smtp.host", _host);
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.connectiontimeout", "20000"); //timeout with mail
//20 sec.
if (_debuggable) {
props.put("mail.debug", "true");
}
if (_auth) {
props.put("mail.smtp.auth", "true");
}
props.put("mail.smtp.port", _port);
props.put("mail.smtp.socketFactory.port", _sport);
props.put("mail.smtp.socketFactory.fallback", "true");
return props;
}
public String getBody() {
return _body;
}
public void setBody(String _body) {
this._body = _body;
}
public void setTo(String[] toArr) {
this._to = toArr;
}
public void setFrom(String string) {
this._from = string;
}
public void setSubject(String string) {
this._subject = string;
}
}
Quand je debug de l'application, la seule application se bloque à cette ligne suivante:
SMIMESignedGenerator signer = new SMIMESignedGenerator();
C'est le seul message d'erreur que je reçois de dalvik:
DexOpt: unable to optimize static field ref 0x0991 at 0x18 in Lorg/bouncycastle/mail/smime/SMIMESignedGenerator;.<clinit>
Tous mes externe .jar
fichiers est situé sous le dossier libs
.
Quelqu'un sait pourquoi cela se produit? Personne a réussi chiffrer un mail avec SMIME/X. 509? Ou est-il un moyen beaucoup plus simple pour faire cela?
OriginalL'auteur Tobias Moe Thorstensen | 2012-09-06
Vous devez vous connecter pour publier un commentaire.
Si je comprends ce que vous essayez d'atteindre, vous n'êtes pas seulement le cryptage d'un message MIME, vous êtes de signature et de chiffrement (et cela doit être fait dans cet ordre)
La BouncyCastle de l'exemple fourni par la signature d'un mail ici
Le BouncyCastle de l'exemple fourni par le chiffrement d'un mail ici
Enfin, la signature d'un groupe musculaire, vous reçoit de type Multipart que vous devez envelopper dans un MimeBodyPart que vous chiffrer, ce qui vous obtient un chiffrés MimeBodyPart qui vous "insérer" dans un MimeMessage (voir le cryptage exemple)
OriginalL'auteur Bruno Grieder