首先,请原谅我的英语水平不高。感谢您的解决方案!
我是bouncycastle的新手。我已经使用它来创建PGPkeypair,获取PGPPublickKey和secretKey。我也使用secretKey来加密txt文件,但是我无法对其进行签名和解密。我的代码几乎来自于org.bouncycastle.openpgp.example我不知道问题出在哪里 这是我的代码:
1,创建PGPKeyPair并获取PGPPublickey,secretKey并保存它们:
public static PGPPublicKey generateKeyPair() throws Exception {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA", "BC");
keyGen.initialize(1024, new SecureRandom());
int algorithm = PGPPublicKey.RSA_GENERAL;
PGPKeyPair pkp=new JcaPGPKeyPair(algorithm, keyGen.generateKeyPair(), new Date());
Security.addProvider(new BouncyCastleProvider());
Security.addProvider(new BouncyCastlePQCProvider());
// 生成RSA密钥对
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC");
kpg.initialize(4096);
KeyPair kp = kpg.generateKeyPair();
// 转为PGP密钥对
JcaPGPKeyPair pgpKeyPair = new JcaPGPKeyPair(PGPPublicKey.RSA_GENERAL,
kp, new Date());
// 用户标识一般使用email
String identity = "fad@163.com";
// 用来保护密钥的密码
char[] passPhrase = "123456".toCharArray();
PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder()
.build().get(HashAlgorithmTags.SHA1);
PGPContentSignerBuilder certSignerBuilder = new JcaPGPContentSignerBuilder(
pgpKeyPair.getPublicKey().getAlgorithm(),
HashAlgorithmTags.SHA1);
PBESecretKeyEncryptor keyEncryptor = new JcePBESecretKeyEncryptorBuilder(
SymmetricKeyAlgorithmTags.AES_256, sha1Calc,0x90).setProvider("BC").build(
passPhrase);
// 生成PGP密钥
PGPSecretKey secretKey = new PGPSecretKey(
PGPSignature.DEFAULT_CERTIFICATION, pgpKeyPair, identity,
sha1Calc, null, null, certSignerBuilder, keyEncryptor);
// 保存PGP密钥到asc文件
File externalStorageDirectory = Environment
.getExternalStorageDirectory();
String path = externalStorageDirectory.toString();
OutputStream secretOut = new ArmoredOutputStream(new FileOutputStream(
path + "/SecretKey.asc"));
secretKey.encode(secretOut);
secretOut.close();
// 保存PGP公钥到asc文件
OutputStream publicOut = new ArmoredOutputStream(new FileOutputStream(
path + "/PublicKey.asc"));
PGPPublicKey key = secretKey.getPublicKey();
key.encode(publicOut);
publicOut.close();
return key;
}
2,使用SignedFileProcessor.java加密文件和解密文件:
public class KeyBasedLargeFileProcessor{
public static void decryptFile(
String inputFileName,
String keyFileName,
char[] passwd,
String defaultFileName)
throws IOException, NoSuchProviderException
{
InputStream in = new BufferedInputStream(new FileInputStream(inputFileName));
InputStream keyIn = new BufferedInputStream(new FileInputStream(keyFileName));
decryptFile(in, keyIn, passwd, defaultFileName);
keyIn.close();
in.close();
}
/**
* decrypt the passed in message stream
*/
public static void decryptFile(
InputStream in,
InputStream keyIn,
char[] passwd,
String defaultFileName)
throws IOException, NoSuchProviderException
{
in = PGPUtil.getDecoderStream(in);
try
{
PGPObjectFactory pgpF = new PGPObjectFactory(in);
PGPEncryptedDataList enc;
Object o = pgpF.nextObject();
//
// the first object might be a PGP marker packet.
//
if (o instanceof PGPEncryptedDataList)
{
enc = (PGPEncryptedDataList)o;
}
else
{
enc = (PGPEncryptedDataList)pgpF.nextObject();
}
//
// find the secret key
//
Iterator it = enc.getEncryptedDataObjects();
PGPPrivateKey sKey = null;
PGPPublicKeyEncryptedData pbe = null;
PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(
PGPUtil.getDecoderStream(keyIn));
while (sKey == null && it.hasNext())
{
pbe = (PGPPublicKeyEncryptedData)it.next();
sKey = PGPExampleUtil.findSecretKey(pgpSec, pbe.getKeyID(), passwd);
}
if (sKey == null)
{
throw new IllegalArgumentException("secret key for message not found.");
}
InputStream clear = pbe.getDataStream(new JcePublicKeyDataDecryptorFactoryBuilder().setProvider("BC").build(sKey));
PGPObjectFactory plainFact = new PGPObjectFactory(clear);
PGPCompressedData cData = (PGPCompressedData)plainFact.nextObject();
InputStream compressedStream = new BufferedInputStream(cData.getDataStream());
PGPObjectFactory pgpFact = new PGPObjectFactory(compressedStream);
Object message = pgpFact.nextObject();
if (message instanceof PGPLiteralData)
{
PGPLiteralData ld = (PGPLiteralData)message;
String outFileName = ld.getFileName();
if (outFileName.length() == 0)
{
outFileName = defaultFileName;
}
InputStream unc = ld.getInputStream();
OutputStream fOut = new BufferedOutputStream(new FileOutputStream(outFileName));
Streams.pipeAll(unc, fOut);
fOut.close();
}
else if (message instanceof PGPOnePassSignatureList)
{
throw new PGPException("encrypted message contains a signed message - not literal data.");
}
else
{
throw new PGPException("message is not a simple encrypted file - type unknown.");
}
if (pbe.isIntegrityProtected())
{
if (!pbe.verify())
{
System.err.println("message failed integrity check");
}
else
{
System.err.println("message integrity check passed");
}
}
else
{
System.err.println("no message integrity check");
}
}
catch (PGPException e)
{
System.err.println(e);
if (e.getUnderlyingException() != null)
{
e.getUnderlyingException().printStackTrace();
}
}
}
public static void encryptFile(
String outputFileName,
String inputFileName,
String encKeyFileName,
boolean armor,
boolean withIntegrityCheck)
throws IOException, NoSuchProviderException, PGPException
{
OutputStream out = new BufferedOutputStream(new FileOutputStream(outputFileName));
PGPPublicKey encKey = PGPExampleUtil.readPublicKey(encKeyFileName);
encryptFile(out, inputFileName, encKey, armor, withIntegrityCheck);
out.close();
}
public static void encryptFile(
OutputStream out,
String fileName,
PGPPublicKey encKey,
boolean armor,
boolean withIntegrityCheck)
throws IOException, NoSuchProviderException
{
if (armor)
{
out = new ArmoredOutputStream(out);
}
try
{
PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(new JcePGPDataEncryptorBuilder(PGPEncryptedData.AES_256).setWithIntegrityPacket(withIntegrityCheck).setSecureRandom(new SecureRandom()).setProvider("BC"));
cPk.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(encKey).setProvider("BC"));
OutputStream cOut = cPk.open(out, new byte[1 << 16]);
PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(
PGPCompressedData.ZIP);
PGPUtil.writeFileToLiteralData(comData.open(cOut), PGPLiteralData.BINARY, new File(fileName), new byte[1 << 16]);
comData.close();
cOut.close();
if (armor)
{
out.close();
}
}
catch (PGPException e)
{
System.err.println(e);
if (e.getUnderlyingException() != null)
{
e.getUnderlyingException().printStackTrace();
}
}
}
}
3,这是我的测试代码: private void test(){
File storageDirectory = Environment.getExternalStorageDirectory();
final String opath = storageDirectory.toString();
final File publcKeyFile = new File(storageDirectory, "PublicKey.asc");
if(!publcKeyFile.exists()){
try {
OpenGPGUtil.generateKeyPair();
} catch (Exception e) {
e.printStackTrace();
}
}else {
System.out.println("密钥存在");
}
final File secretKeyFile = new File(storageDirectory, "SecretKey.asc");
final File enFile = new File(storageDirectory, "s.txt");
final File file = new File(storageDirectory, "x.txt");
final File deFile = new File(storageDirectory, "ss.txt");
final String publcKeyfilePath = publcKeyFile.toString();
final String secretKeyFilePath = secretKeyFile.toString();
final String enFilePath = enFile.toString();
final String filePath = file.toString();
final String deFilePath = deFile.toString();
new Thread(new Runnable() {
@Override
public void run() {
try {
KeyBasedLargeFileProcessor.encryptFile(enFilePath,
filePath, publcKeyfilePath, true, true);
// KeyBasedLargeFileProcessor.decryptFile(enFilePath,
// secretKeyFilePath, "123456".toCharArray(),
// deFilePath);
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
以下是三行注释,如果我删除它们,Eclipse的logcat将显示:
/System.err(7498): java.io.FileNotFoundException:
/x.txt: open failed: EROFS (Read-only file system)
System.err(7498): at libcore.io.IoBridge.open(IoBridge.java:409)
System.err(7498): at java.io.FileOutputStream
<init(FileOutputStream.java:88)
System.err(7498): at java.io.FileOutputStream
.<init> (FileOutputStream.java:128)
System.err(7498): at java.io.FileOutputStream
.<init>(FileOutputStream.java:117)
System.err(7498): at com.example.opengpgs.KeyBasedLargeFileProcessor.
decryptFile(KeyBasedLargeFileProcessor.java:147)
System.err(7498): at com.example.opengpgs.KeyBasedLargeFileProcessor
.decryptFile(KeyBasedLargeFileProcessor.java:69)
System.err(7498): at com.example.opengpgs.MainActivity$1.
run(MainActivity.java:62)
System.err(7498): at java.lang.Thread.run(Thread.java:841)
System.err(7498): Caused by: libcore.io.ErrnoException:
open failed: EROFS (Read-only file system)
System.err(7498): at libcore.io.Posix.open(Native Method)
System.err(7498): at libcore.io.BlockGuardOs.
open(BlockGuardOs.java:110)
System.err(7498): at libcore.io.IoBridge.open(IoBridge.java:393)
System.err(7498): ... 7 more
IInputConnectionWrapper(7498): getCursorCapsMode on
inactive InputConnection
答案 0 :(得分:1)
从错误来看,您的文件系统似乎是只读的,但您正在尝试将其写入文件x.txt