我使用lib Spongy Castle根据this example在Android上签名和加密邮件。
/* Add BC */
Security.addProvider(new BouncyCastleProvider());
/* Open the keystore */
KeyStore keystore = KeyStore.getInstance("PKCS12", "SC");
keystore.load(new FileInputStream(pkcs12Keystore),
password.toCharArray());
Certificate[] chain = keystore.getCertificateChain(keyalias);
/* Get the private key to sign the message with */
PrivateKey privateKey = (PrivateKey) keystore.getKey(keyalias,
password.toCharArray());
/* Create the 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 IssuerAndSerialNumber(new X500Name(
((X509Certificate) chain[0]).getIssuerDN()
.getName()), ((X509Certificate) chain[0])
.getSerialNumber())));
attributes.add(new SMIMECapabilitiesAttribute(capabilities));
SMIMESignedGenerator signer = new SMIMESignedGenerator();
signer.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder()
.setProvider("SC")
.setSignedAttributeGenerator(new AttributeTable(attributes))
.build("DSA".equals(privateKey.getAlgorithm()) ? "SHA1withDSA"
: "MD5withDSA", privateKey,
(X509Certificate) chain[0]));
/* Add the list of certs to the generator */
List certList = new ArrayList();
certList.add(chain[0]);
Store certs = new JcaCertStore(certList);
signer.addCertificates(certs);
/* Sign the message */
MimeMultipart mm = signer.generate(originalMessage, "SC");
signedMessage = new MimeMessage(session);
/* Set all original MIME headers in the signed message */
Enumeration headers = originalMessage.getAllHeaderLines();
while (headers.hasMoreElements()) {
signedMessage.addHeaderLine((String) headers.nextElement());
}
/* Set the content of the signed message */
signedMessage.setContent(mm);
signedMessage.saveChanges();
ByteArrayOutputStream out = new ByteArrayOutputStream();
signedMessage.writeTo(out);
FileOutputStream f = new FileOutputStream(new File(
"/sdcard/MobilePKI/out.txt"));
f.write(out.toByteArray());
f.close();
当我运行我的应用时,它会返回以下错误:
11-13 08:54:11.867: E/dalvikvm(13188): Could not find class '[Ljava.awt.datatransfer.DataFlavor;', referenced from method org.spongycastle.mail.smime.handlers.multipart_signed.<clinit>
11-13 08:54:11.890: E/AndroidRuntime(13188): FATAL EXCEPTION: main
11-13 08:54:11.890: E/AndroidRuntime(13188): java.lang.VerifyError: org.spongycastle.mail.smime.handlers.multipart_signed
11-13 08:54:11.890: E/AndroidRuntime(13188): at java.lang.Class.newInstanceImpl(Native Method)
11-13 08:54:11.890: E/AndroidRuntime(13188): at java.lang.Class.newInstance(Class.java:1409)
11-13 08:54:11.890: E/AndroidRuntime(13188): at javax.activation.MailcapCommandMap.getDataContentHandler(MailcapCommandMap.java:609)
11-13 08:54:11.890: E/AndroidRuntime(13188): at javax.activation.MailcapCommandMap.createDataContentHandler(MailcapCommandMap.java:563)
11-13 08:54:11.890: E/AndroidRuntime(13188): at javax.activation.DataHandler.getDataContentHandler(DataHandler.java:626)
11-13 08:54:11.890: E/AndroidRuntime(13188): at javax.activation.DataHandler.writeTo(DataHandler.java:329)
11-13 08:54:11.890: E/AndroidRuntime(13188): at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1403)
11-13 08:54:11.890: E/AndroidRuntime(13188): at javax.mail.internet.MimeMessage.writeTo(MimeMessage.java:1745)
11-13 08:54:11.890: E/AndroidRuntime(13188): at javax.mail.internet.MimeMessage.writeTo(MimeMessage.java:1721)
Spongy Castle lib的源代码似乎需要java.awt.datatransfer:
package org.spongycastle.mail.smime.handlers;
import org.spongycastle.mail.smime.SMIMEStreamingProcessor;
import javax.activation.ActivationDataFlavor;
import javax.activation.DataContentHandler;
import javax.activation.DataSource;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.internet.ContentType;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMultipart;
import java.awt.datatransfer.DataFlavor;
import java.io.BufferedInputStream;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
我认为它必须导入包java.awt并且我将rt.jar(包括java.awt。*)导入到我的项目中但它仍然有这个错误。
答案 0 :(得分:0)
我修正了错误:
+我下载spongycastle lib的源代码
+替换行“import java.awt.datatransfer.DataFlavor;”通过“import myjava.awt.datatransfer.DataFlavor;” (包含myjava.awt.datatransfer包含在additionnal lib)中
+重建spongycastle lib
+使用新的spongycastle lib
答案 1 :(得分:0)
我设法解决了这个问题:
0)在邮件包上运行become-spongy.sh脚本(来自“spongy-scripts”分支) 1)在mail / src / main /
中创建AndroidManifest.xml<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.spongycastle">
</manifest>
2)更改mail / build.gradle
apply plugin: 'com.android.library'
dependencies {
compile 'com.sun.mail:android-mail:1.5.5'
compile 'com.sun.mail:android:1.5.5'
compile 'com.madgag.spongycastle:pkix:1.54.0.0'
compile 'com.madgag.spongycastle:prov:1.54.0.0'
compile 'com.madgag.spongycastle:core:1.54.0.0'
testCompile 'junit:junit:4.12'
}
android {
compileSdkVersion 24
buildToolsVersion "24.0.0"
defaultConfig {
minSdkVersion 15
targetSdkVersion 24
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
3)在处理程序文件中(spongycastle / mail / src / main / java / org / spongycastle / mail / smime / handlers /):
a)删除import java.awt.datatransfer.DataFlavor
b)删除用javax.activation.ActivationDataFlavor替换java.awt.datatransfer.DataFlavor变量/返回类型
4)在你的android项目中将该文件夹包含为模块
5)建立并享受乐趣; D
在这里,您可以看到工作的spongycastle邮件包的外观如何:https://github.com/Skywalker-11/spongycastle
这是一个关于Android应用程序如何使用固定版本通过smtp发送加密smime消息的示例https://github.com/Skywalker-11/SpongyCastleMailTestApp