[英]Getting NoSuchMethodError at using Spongycastle with iText on Android
I was trying to sign a PDF document with iText on Android. 我试图在Android上使用iText签署PDF文档。 The certificate was included and activated in the emulator.
该证书已包括在仿真器中并已激活。 Here are the libraries I used:
这是我使用的库:
compile 'com.android.support:appcompat-v7:23.2.0'
compile 'com.itextpdf:itextg:5.5.9'
testCompile 'junit:junit:4.12'
compile files('libs/itext-licensekey-1.0.4.jar')
compile 'com.madgag.spongycastle:core:1.54.0.0'
compile 'com.madgag.spongycastle:prov:1.54.0.0'
compile 'com.madgag.spongycastle:pkix:1.54.0.0'
compile 'com.madgag.spongycastle:pg:1.54.0.0'
Following is the class that I used to sign existing pdf document: 以下是我用来签署现有pdf文档的课程:
public class SignPDF {
static {
Security.insertProviderAt(new org.spongycastle.jce.provider.BouncyCastleProvider(), 1);
}
public void sign(String src, String dest,
Certificate[] chain, PrivateKey pk, String digestAlgorithm, String provider,
MakeSignature.CryptoStandard subfilter, String reason, String location)
throws GeneralSecurityException, IOException, DocumentException {
PdfReader reader = new PdfReader(src);
FileOutputStream os = new FileOutputStream(dest);
PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0');
PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
appearance.setReason(reason);
appearance.setLocation(location);
appearance.setVisibleSignature(new Rectangle(36, 748, 144, 780), 1, "sig");
ExternalDigest digest = new BouncyCastleDigest();
ExternalSignature signature =
new PrivateKeySignature(pk, digestAlgorithm, provider);
MakeSignature.signDetached(appearance, digest, signature, chain,
null, null, null, 0, subfilter);
}
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE};
private static final int REQUEST_EXTERNAL_STORAGE = 1;
public static final String SRC = Environment.getExternalStorageDirectory() + File.separator + "testdsign_1.pdf"; // consider the file to be created earlier
public static final String DEST = Environment.getExternalStorageDirectory() + File.separator + "testdsign_2.pdf";
public static void signat(Activity a)
throws IOException, GeneralSecurityException {
int permission = ActivityCompat.checkSelfPermission(a, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(
a,
PERMISSIONS_STORAGE,
REQUEST_EXTERNAL_STORAGE
);
}
String path = Environment.getExternalStorageDirectory() + File.separator + "keystore.p12";
char[] pass = "123456".toCharArray();
BouncyCastleProvider provider = new BouncyCastleProvider();
Security.addProvider(provider);
KeyStore ks = KeyStore.getInstance("pkcs12", provider.getName());
ks.load(new FileInputStream(path), pass);
String alias = (String) ks.aliases().nextElement();
PrivateKey pk = (PrivateKey) ks.getKey(alias, pass);
Certificate[] chain = ks.getCertificateChain(alias);
SignPDF app = new SignPDF();
try {
app.sign(SRC, DEST, chain, pk, DigestAlgorithms.SHA256, provider.getName(),
MakeSignature.CryptoStandard.CMS, "Test", "Ghent");
} catch (DocumentException e) {
e.printStackTrace();
}
}
} }
Finally, the error stack 最后,错误堆栈
java.lang.NoSuchMethodError: No direct method <init>(I)V in class Lorg/spongycastle/asn1/ASN1Integer; or its super classes (declaration of 'org.spongycastle.asn1.ASN1Integer' appears in /data/data/dsign.example.com.dsigntest/files/instant-run/dex/slice-core-1.54.0.0_016eb8590d95a10a91a6367c6ca7de97121683a4-classes.dex)
at com.itextpdf.text.pdf.security.PdfPKCS7.getEncodedPKCS7(PdfPKCS7.java:826)
at com.itextpdf.text.pdf.security.MakeSignature.signDetached(MakeSignature.java:154)
at dsign.example.com.dsigntest.SignPDF.sign(SignPDF.java:56)
at dsign.example.com.dsigntest.SignPDF.signat(SignPDF.java:91)
at dsign.example.com.dsigntest.MainActivity.onCreate(MainActivity.java:59)
at android.app.Activity.performCreate(Activity.java:6237)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
What is the cause of the problem? 是什么原因引起的? Thank you for any kind of help.
谢谢您的帮助。
You are using BouncyCastle version 1.54. 您正在使用BouncyCastle版本1.54。 iTextG 5.5.* requires SpongyCastle version 1.47.0.2 (meanwhile iText 5.5.* requires BouncyCastle version 1.49).
iTextG 5.5。*需要SpongyCastle版本1.47.0.2(同时iText 5.5。*需要BouncyCastle版本1.49)。
The recommended way is to add iTextG to your Maven/Gradle/... config as a dependency, and your build tool will automatically pull in the correct version of SpongyCastle, which is currently 1.47.0.2. 推荐的方法是将iTextG作为依赖项添加到Maven / Gradle / ...配置中,并且构建工具将自动拉入正确的SpongyCastle版本,当前版本为1.4.7.0.2。 There is no need to manually hunt for dependencies.
无需手动寻找依赖关系。 Dependency resolution is a solved problem on Android.
依赖性解析是Android上已解决的问题。
EDIT: 编辑:
Some people apparently don't the Maven build tool (or Gradle), but manually search for jars on http://search.maven.org . 有些人显然不是Maven构建工具(或Gradle),而是在http://search.maven.org上手动搜索jar。 If you do that, and you blindly search for "spongycastle", then you will only find the wrong version.
如果这样做,并且盲目搜索“ spongycastle”,则只会找到错误的版本。
As one can see in the iTextG pom.xml
: 在iTextG
pom.xml
可以看到:
<dependencies>
<dependency>
<groupId>com.madgag</groupId>
<artifactId>scprov-jdk15on</artifactId>
<version>1.47.0.2</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.madgag</groupId>
<artifactId>scpkix-jdk15on</artifactId>
<version>1.47.0.2</version>
<optional>true</optional>
</dependency>
...
</dependencies>
I repeat, these are the correct dependencies for iText 5.5.*: 我重复一遍,这些是iText 5.5。*的正确依赖项:
com.madgag
com.madgag
scprov-jdk15on
and scpkix-jdk15on
scprov-jdk15on
和scpkix-jdk15on
1.47.0.2
1.47.0.2
These dependencies are WRONG for iText 5.5.*: 这些依赖性对于iText 5.5。*是错误的:
com.madgag.spongycastle
com.madgag.spongycastle
prov
and pkix
prov
和pkix
[1.50,)
[1.50,)
If, after making sure that you use the correct version of SpongyCastle, you still have issues, then you have to ask a NEW question. 如果在确保使用正确版本的SpongyCastle之后仍然存在问题,则必须提出一个新问题。 In your question, include the following information:
在您的问题中,包括以下信息:
mvn dependency:tree -Dverbose
mvn dependency:tree -Dverbose
输出mvn dependency:tree -Dverbose
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.