Improve comments and reasons in PgpConstants, simple checks for insecure asymmetric keys
This commit is contained in:
@@ -94,15 +94,15 @@ dependencyVerification {
|
||||
'com.mikepenz.iconics:meteocons-typeface:39a8a9e70cd8287cdb119af57a672a41dd09240dba6697f5a0dbda1ccc33298b',
|
||||
'com.mikepenz.iconics:community-material-typeface:f1c5afee5f0f10d66beb3ed0df977246a02a9c46de4e05d7c0264bcde53b6b7f',
|
||||
'com.squareup.okhttp:okhttp:bc0da7ac1f5441619faa2082811938acf7df97e4a8e08f0e043ff4937414d5ad',
|
||||
// 'OpenKeychain.extern.openpgp-api-lib:openpgp-api:b918e50a7876fad34e4020ee41418039772c5fe8dd36825720ca8ffecb7d0f06',
|
||||
// 'OpenKeychain.extern.openkeychain-api-lib:openkeychain-intents:111d7d53b9e920ad3405f8f3eb0ab7bd3aee66d577442452754b83c7c1c1d49a',
|
||||
// 'com.madgag.spongycastle:core:97276487be598747ba78c063c90cea7fc3c7ad9bc7aeba03c0b9c98692052b8a',
|
||||
// 'com.madgag.spongycastle:pg:da319de706d946f178140959c74aec126f7803f1104dbad89bb1f55a53f6e1a9',
|
||||
// 'com.madgag.spongycastle:pkix:979aa4b2aaef94866e0f97b05b1922244eaf8b650f3691a3c44760ff0a41562b',
|
||||
// 'com.madgag.spongycastle:prov:902a484219bbf4e395a1c32da65b2453133e195bcc92336dc8c33b7c58edcd60',
|
||||
// 'OpenKeychain.extern:minidns:8274d50124d9584e95df0c5da7798269ac9caf0eab560df929c2c658ca624037',
|
||||
// 'OpenKeychain.extern.KeybaseLib:Lib:d52e7888cea6de9e077501bb533270b2a86b52cb8af49e5f44ee8c4bb19ea017',
|
||||
// 'OpenKeychain.extern.safeslinger-exchange:safeslinger-exchange:76e5da6b4f5f8835b12649e17569f0d0d8d89552815a61383c128545632689d1',
|
||||
// 'OpenKeychain.extern.openpgp-api-lib:openpgp-api:bbbc0b964757450ec78823ec448b0754999e16c9c620e3587c14289cba8e87f8',
|
||||
// 'OpenKeychain.extern.openkeychain-api-lib:openkeychain-intents:4b2f5637580b9bad786d57c32e8b86d6554e2d4ed55ccbfb028bbece655100cc',
|
||||
// 'OpenKeychain.extern.spongycastle:core:4a2a3c86616944bfdaf8f3148a9e047d5007433f1af0a4b38a552b4ec94f6804',
|
||||
// 'OpenKeychain.extern.spongycastle:pg:44690d345d806626d0a83eb5434ba9b52ccfcb37f5a775842333470658ffe28f',
|
||||
// 'OpenKeychain.extern.spongycastle:pkix:bb08d67b726bcf09018cac43c57dfaa00bb7540d16e6e986f0378feb0fed5327',
|
||||
// 'OpenKeychain.extern.spongycastle:prov:b9f0df403c1c9ac6ec7b0bb138fd8dda3d1ac72983c7a5e4a6dc9deab1d7a11e',
|
||||
// 'OpenKeychain.extern:minidns:feb3bbbb3ce15e6e2a4711b35695a54f420188e4264b87116a03b8374b74eb86',
|
||||
// 'OpenKeychain.extern.KeybaseLib:Lib:c80857e2347fb0a80f48a0da8aa510cdfe7c2486784af1d17fb385382f45fe6c',
|
||||
// 'OpenKeychain.extern.safeslinger-exchange:safeslinger-exchange:781c4a5723b6a3c68d1178ac67908cd250d7bac6f11c39836618cc8fc8d0177f',
|
||||
// 'OpenKeychain.extern.snackbar:lib:6847a73d2680558d35f0b384ac3ed006532c0a2306598b000db94ef18aab62aa',
|
||||
'com.android.support:support-annotations:beac5cae60bdb597df9af9c916f785c2f71f8c8ae4be9a32d4298dea85496a42',
|
||||
'com.squareup.okio:okio:b53c1760864e1c39b5275d9023e2a6fbe8f3189e6e67b4c87877b8ec8f92e05a',
|
||||
@@ -110,6 +110,7 @@ dependencyVerification {
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
android {
|
||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||
buildToolsVersion rootProject.ext.buildToolsVersion
|
||||
|
||||
@@ -611,14 +611,12 @@ public abstract class OperationResult implements Parcelable {
|
||||
MSG_DC_ERROR_CORRUPT_DATA (LogLevel.ERROR, R.string.msg_dc_error_corrupt_data),
|
||||
MSG_DC_ERROR_EXTRACT_KEY (LogLevel.ERROR, R.string.msg_dc_error_extract_key),
|
||||
MSG_DC_ERROR_INTEGRITY_CHECK (LogLevel.ERROR, R.string.msg_dc_error_integrity_check),
|
||||
MSG_DC_ERROR_INTEGRITY_MISSING (LogLevel.ERROR, R.string.msg_dc_error_integrity_missing),
|
||||
MSG_DC_ERROR_INVALID_DATA (LogLevel.ERROR, R.string.msg_dc_error_invalid_data),
|
||||
MSG_DC_ERROR_IO (LogLevel.ERROR, R.string.msg_dc_error_io),
|
||||
MSG_DC_ERROR_INPUT (LogLevel.ERROR, R.string.msg_dc_error_input),
|
||||
MSG_DC_ERROR_NO_DATA (LogLevel.ERROR, R.string.msg_dc_error_no_data),
|
||||
MSG_DC_ERROR_NO_KEY (LogLevel.ERROR, R.string.msg_dc_error_no_key),
|
||||
MSG_DC_ERROR_PGP_EXCEPTION (LogLevel.ERROR, R.string.msg_dc_error_pgp_exception),
|
||||
MSG_DC_ERROR_UNSUPPORTED_HASH_ALGO (LogLevel.ERROR, R.string.msg_dc_error_unsupported_hash_algo),
|
||||
MSG_DC_INTEGRITY_CHECK_OK (LogLevel.INFO, R.string.msg_dc_integrity_check_ok),
|
||||
MSG_DC_OK_META_ONLY (LogLevel.OK, R.string.msg_dc_ok_meta_only),
|
||||
MSG_DC_OK (LogLevel.OK, R.string.msg_dc_ok),
|
||||
@@ -633,7 +631,10 @@ public abstract class OperationResult implements Parcelable {
|
||||
MSG_DC_TRAIL_SYM (LogLevel.DEBUG, R.string.msg_dc_trail_sym),
|
||||
MSG_DC_TRAIL_UNKNOWN (LogLevel.DEBUG, R.string.msg_dc_trail_unknown),
|
||||
MSG_DC_UNLOCKING (LogLevel.INFO, R.string.msg_dc_unlocking),
|
||||
MSG_DC_OLD_SYMMETRIC_ENCRYPTION_ALGO (LogLevel.WARN, R.string.msg_dc_old_symmetric_encryption_algo),
|
||||
MSG_DC_INSECURE_SYMMETRIC_ENCRYPTION_ALGO(LogLevel.WARN, R.string.msg_dc_insecure_symmetric_encryption_algo),
|
||||
MSG_DC_INSECURE_HASH_ALGO(LogLevel.ERROR, R.string.msg_dc_insecure_hash_algo),
|
||||
MSG_DC_INSECURE_MDC_MISSING(LogLevel.ERROR, R.string.msg_dc_insecure_mdc_missing),
|
||||
MSG_DC_INSECURE_KEY(LogLevel.ERROR, R.string.msg_dc_insecure_key),
|
||||
|
||||
// verify signed literal data
|
||||
MSG_VL (LogLevel.INFO, R.string.msg_vl),
|
||||
|
||||
@@ -43,7 +43,6 @@ import org.sufficientlysecure.keychain.util.Passphrase;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.interfaces.RSAPrivateCrtKey;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -195,7 +194,7 @@ public class CanonicalizedSecretKey extends CanonicalizedPublicKey {
|
||||
|
||||
public PGPSignatureGenerator getCertSignatureGenerator(Map<ByteBuffer, byte[]> signedHashes) {
|
||||
PGPContentSignerBuilder contentSignerBuilder = getContentSignerBuilder(
|
||||
PgpConstants.CERTIFY_HASH_ALGO, signedHashes);
|
||||
PgpSecurityConstants.CERTIFY_HASH_ALGO, signedHashes);
|
||||
|
||||
if (mPrivateKeyState == PRIVATE_KEY_STATE_LOCKED) {
|
||||
throw new PrivateKeyNotUnlockedException();
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.sufficientlysecure.keychain.pgp;
|
||||
|
||||
import org.openintents.openpgp.OpenPgpDecryptionResult;
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
|
||||
public class OpenPgpDecryptionResultBuilder {
|
||||
|
||||
// builder
|
||||
private boolean mInsecure = false;
|
||||
private boolean mEncrypted = false;
|
||||
|
||||
public void setInsecure(boolean insecure) {
|
||||
this.mInsecure = insecure;
|
||||
}
|
||||
|
||||
public void setEncrypted(boolean encrypted) {
|
||||
this.mEncrypted = encrypted;
|
||||
}
|
||||
|
||||
public OpenPgpDecryptionResult build() {
|
||||
OpenPgpDecryptionResult result = new OpenPgpDecryptionResult();
|
||||
|
||||
if (mInsecure) {
|
||||
Log.d(Constants.TAG, "RESULT_INSECURE");
|
||||
result.setResult(OpenPgpDecryptionResult.RESULT_INSECURE);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (mEncrypted) {
|
||||
Log.d(Constants.TAG, "RESULT_ENCRYPTED");
|
||||
result.setResult(OpenPgpDecryptionResult.RESULT_ENCRYPTED);
|
||||
} else {
|
||||
Log.d(Constants.TAG, "RESULT_NOT_ENCRYPTED");
|
||||
result.setResult(OpenPgpDecryptionResult.RESULT_NOT_ENCRYPTED);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,174 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.sufficientlysecure.keychain.pgp;
|
||||
|
||||
import org.spongycastle.bcpg.CompressionAlgorithmTags;
|
||||
import org.spongycastle.bcpg.HashAlgorithmTags;
|
||||
import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* NIST requirements for 2011-2030 (http://www.keylength.com/en/4/):
|
||||
* - RSA: 2048 bit
|
||||
* - ECC: 224 bit
|
||||
* - Symmetric: 3TDEA
|
||||
* - Digital Signature (hash A): SHA-224 - SHA-512
|
||||
*
|
||||
* Many decisions are based on https://gist.github.com/coruus/68a8c65571e2b4225a69
|
||||
*/
|
||||
public class PgpConstants {
|
||||
|
||||
// public interface MIN_REQUIREMENT {
|
||||
// int MIN_BITS;
|
||||
// int BINDING_SIGNATURE_HASH_ALGO; // for User IDs, subkeys,...
|
||||
// int SYMMETRIC_ALGO;
|
||||
// }
|
||||
// https://tools.ietf.org/html/rfc6637#section-13
|
||||
|
||||
/*
|
||||
PgpDecryptVerify: Secure Algorithms Whitelist
|
||||
all other algorithms will be rejected with OpenPgpDecryptionResult.RESULT_INSECURE
|
||||
|
||||
No broken ciphers or ciphers with key length smaller than 128 bit are allowed!
|
||||
*/
|
||||
public static HashSet<Integer> sSymmetricAlgorithmsWhitelist = new HashSet<>();
|
||||
static {
|
||||
sSymmetricAlgorithmsWhitelist.add(SymmetricKeyAlgorithmTags.AES_256);
|
||||
sSymmetricAlgorithmsWhitelist.add(SymmetricKeyAlgorithmTags.AES_192);
|
||||
sSymmetricAlgorithmsWhitelist.add(SymmetricKeyAlgorithmTags.AES_128);
|
||||
sSymmetricAlgorithmsWhitelist.add(SymmetricKeyAlgorithmTags.TWOFISH); // 128 bit
|
||||
}
|
||||
|
||||
// all other algorithms will be rejected with OpenPgpSignatureResult.RESULT_INVALID_INSECURE
|
||||
public static HashSet<Integer> sHashAlgorithmsWhitelist = new HashSet<>();
|
||||
static {
|
||||
sHashAlgorithmsWhitelist.add(HashAlgorithmTags.SHA512);
|
||||
sHashAlgorithmsWhitelist.add(HashAlgorithmTags.SHA384);
|
||||
/*
|
||||
TODO: SHA256 and SHA224 are still allowed even though
|
||||
coruus advises against it, to enable better backward compatibility
|
||||
|
||||
coruus:
|
||||
Implementations MUST NOT sign SHA-224 hashes. They SHOULD NOT accept signatures over SHA-224 hashes.
|
||||
((collision resistance of 112-bits))
|
||||
Implementations SHOULD NOT sign SHA-256 hashes. They MUST NOT default to signing SHA-256 hashes.
|
||||
*/
|
||||
sHashAlgorithmsWhitelist.add(HashAlgorithmTags.SHA256);
|
||||
sHashAlgorithmsWhitelist.add(HashAlgorithmTags.SHA224);
|
||||
}
|
||||
|
||||
/*
|
||||
* Most preferred is first
|
||||
* These arrays are written as preferred algorithms into the keys on creation.
|
||||
* Other implementations may choose to honor this selection.
|
||||
*/
|
||||
public static final int[] PREFERRED_SYMMETRIC_ALGORITHMS = new int[]{
|
||||
SymmetricKeyAlgorithmTags.AES_256,
|
||||
SymmetricKeyAlgorithmTags.AES_192,
|
||||
SymmetricKeyAlgorithmTags.AES_128,
|
||||
};
|
||||
|
||||
/*
|
||||
coorus:
|
||||
Implementations SHOULD use SHA-512 for RSA or DSA signatures. They SHOULD NOT use SHA-384.
|
||||
((cite to affine padding attacks; unproven status of RSA-PKCSv15))
|
||||
*/
|
||||
public static final int[] PREFERRED_HASH_ALGORITHMS = new int[]{
|
||||
HashAlgorithmTags.SHA512,
|
||||
};
|
||||
|
||||
/*
|
||||
* Prefer ZIP
|
||||
* "ZLIB provides no benefit over ZIP and is more malleable"
|
||||
* - (OpenPGP WG mailinglist: "[openpgp] Intent to deprecate: Insecure primitives")
|
||||
* BZIP2: very slow
|
||||
*/
|
||||
public static final int[] PREFERRED_COMPRESSION_ALGORITHMS = new int[]{
|
||||
CompressionAlgorithmTags.ZIP,
|
||||
};
|
||||
|
||||
public static final int CERTIFY_HASH_ALGO = HashAlgorithmTags.SHA512;
|
||||
|
||||
|
||||
/*
|
||||
Always use AES-256! Ignore the preferred encryption algos of the recipient!
|
||||
|
||||
coorus:
|
||||
Implementations SHOULD ignore the symmetric algorithm preferences of a recipient's public key;
|
||||
in particular, implementations MUST NOT choose an algorithm forbidden by this
|
||||
document because a recipient prefers it.
|
||||
|
||||
NEEDCITE downgrade attacks on TLS, other protocols
|
||||
*/
|
||||
public static final int DEFAULT_SYMMETRIC_ALGORITHM = SymmetricKeyAlgorithmTags.AES_256;
|
||||
public interface OpenKeychainSymmetricKeyAlgorithmTags extends SymmetricKeyAlgorithmTags {
|
||||
int USE_DEFAULT = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
Always use SHA-512! Ignore the preferred hash algos of the recipient!
|
||||
|
||||
coorus:
|
||||
Implementations MUST ignore the hash algorithm preferences of a recipient when signing
|
||||
a message to a recipient. The difficulty of forging a signature under a given key,
|
||||
using generic attacks on hash functions, is the difficulty of the weakest hash signed by that key.
|
||||
|
||||
Implementations MUST default to using SHA-512 for RSA signatures,
|
||||
|
||||
and either SHA-512 or the matched instance of SHA-2 for ECDSA signatures.
|
||||
TODO: Ed25519
|
||||
CITE: zooko's hash function table CITE: distinguishers on SHA-256
|
||||
*/
|
||||
public static final int DEFAULT_HASH_ALGORITHM = HashAlgorithmTags.SHA512;
|
||||
public interface OpenKeychainHashAlgorithmTags extends HashAlgorithmTags {
|
||||
int USE_DEFAULT = -1;
|
||||
}
|
||||
|
||||
public static final int DEFAULT_COMPRESSION_ALGORITHM = CompressionAlgorithmTags.ZIP;
|
||||
public interface OpenKeychainCompressionAlgorithmTags extends CompressionAlgorithmTags {
|
||||
int USE_DEFAULT = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note: s2kcount is a number between 0 and 0xff that controls the
|
||||
* number of times to iterate the password hash before use. More
|
||||
* iterations are useful against offline attacks, as it takes more
|
||||
* time to check each password. The actual number of iterations is
|
||||
* rather complex, and also depends on the hash function in use.
|
||||
* Refer to Section 3.7.1.3 in rfc4880.txt. Bigger numbers give
|
||||
* you more iterations. As a rough rule of thumb, when using
|
||||
* SHA256 as the hashing function, 0x10 gives you about 64
|
||||
* iterations, 0x20 about 128, 0x30 about 256 and so on till 0xf0,
|
||||
* or about 1 million iterations. The maximum you can go to is
|
||||
* 0xff, or about 2 million iterations.
|
||||
* from http://kbsriram.com/2013/01/generating-rsa-keys-with-bouncycastle.html
|
||||
*
|
||||
* Bouncy Castle default: 0x60
|
||||
* kbsriram proposes: 0xc0
|
||||
* OpenKeychain: 0x90
|
||||
*/
|
||||
public static final int SECRET_KEY_ENCRYPTOR_S2K_COUNT = 0x90;
|
||||
public static final int SECRET_KEY_ENCRYPTOR_HASH_ALGO = HashAlgorithmTags.SHA512;
|
||||
public static final int SECRET_KEY_ENCRYPTOR_SYMMETRIC_ALGO = SymmetricKeyAlgorithmTags.AES_256;
|
||||
public static final int SECRET_KEY_BINDING_SIGNATURE_HASH_ALGO = HashAlgorithmTags.SHA512;
|
||||
// NOTE: only SHA1 is supported for key checksum calculations in OpenPGP,
|
||||
// see http://tools.ietf.org/html/rfc488 0#section-5.5.3
|
||||
public static final int SECRET_KEY_SIGNATURE_CHECKSUM_HASH_ALGO = HashAlgorithmTags.SHA1;
|
||||
|
||||
}
|
||||
@@ -321,7 +321,7 @@ public class PgpDecryptVerify extends BaseOperation<PgpDecryptVerifyInputParcel>
|
||||
InputStream in, OutputStream out, int indent) throws IOException, PGPException {
|
||||
|
||||
OpenPgpSignatureResultBuilder signatureResultBuilder = new OpenPgpSignatureResultBuilder();
|
||||
OpenPgpDecryptionResult decryptionResult = new OpenPgpDecryptionResult();
|
||||
OpenPgpDecryptionResultBuilder decryptionResultBuilder = new OpenPgpDecryptionResultBuilder();
|
||||
OperationLog log = new OperationLog();
|
||||
|
||||
log.add(LogType.MSG_DC, indent);
|
||||
@@ -464,6 +464,12 @@ public class PgpDecryptVerify extends BaseOperation<PgpDecryptVerifyInputParcel>
|
||||
}
|
||||
}
|
||||
|
||||
// check for insecure encryption key
|
||||
if ( ! PgpSecurityConstants.isSecureKey(secretEncryptionKey)) {
|
||||
log.add(LogType.MSG_DC_INSECURE_KEY, indent + 1);
|
||||
decryptionResultBuilder.setInsecure(true);
|
||||
}
|
||||
|
||||
// break out of while, only decrypt the first packet where we have a key
|
||||
break;
|
||||
|
||||
@@ -614,12 +620,12 @@ public class PgpDecryptVerify extends BaseOperation<PgpDecryptVerifyInputParcel>
|
||||
log.add(LogType.MSG_DC_ERROR_NO_KEY, indent + 1);
|
||||
return new DecryptVerifyResult(DecryptVerifyResult.RESULT_ERROR, log);
|
||||
}
|
||||
decryptionResult.setResult(OpenPgpDecryptionResult.RESULT_ENCRYPTED);
|
||||
decryptionResultBuilder.setEncrypted(true);
|
||||
|
||||
// Check for insecure encryption algorithms!
|
||||
if (!PgpConstants.sSymmetricAlgorithmsWhitelist.contains(symmetricEncryptionAlgo)) {
|
||||
log.add(LogType.MSG_DC_OLD_SYMMETRIC_ENCRYPTION_ALGO, indent + 1);
|
||||
decryptionResult.setResult(OpenPgpDecryptionResult.RESULT_INSECURE);
|
||||
if (!PgpSecurityConstants.isSecureSymmetricAlgorithm(symmetricEncryptionAlgo)) {
|
||||
log.add(LogType.MSG_DC_INSECURE_SYMMETRIC_ENCRYPTION_ALGO, indent + 1);
|
||||
decryptionResultBuilder.setInsecure(true);
|
||||
}
|
||||
|
||||
JcaPGPObjectFactory plainFact = new JcaPGPObjectFactory(clear);
|
||||
@@ -687,6 +693,13 @@ public class PgpDecryptVerify extends BaseOperation<PgpDecryptVerifyInputParcel>
|
||||
}
|
||||
}
|
||||
|
||||
// check for insecure signing key
|
||||
// TODO: checks on signingRing ?
|
||||
if (signingKey != null && ! PgpSecurityConstants.isSecureKey(signingKey)) {
|
||||
log.add(LogType.MSG_DC_INSECURE_KEY, indent + 1);
|
||||
signatureResultBuilder.setInsecure(true);
|
||||
}
|
||||
|
||||
dataChunk = plainFact.nextObject();
|
||||
}
|
||||
|
||||
@@ -821,8 +834,8 @@ public class PgpDecryptVerify extends BaseOperation<PgpDecryptVerifyInputParcel>
|
||||
}
|
||||
|
||||
// check for insecure hash algorithms
|
||||
if (!PgpConstants.sHashAlgorithmsWhitelist.contains(signature.getHashAlgorithm())) {
|
||||
log.add(LogType.MSG_DC_ERROR_UNSUPPORTED_HASH_ALGO, indent + 1);
|
||||
if (!PgpSecurityConstants.isSecureHashAlgorithm(signature.getHashAlgorithm())) {
|
||||
log.add(LogType.MSG_DC_INSECURE_HASH_ALGO, indent + 1);
|
||||
signatureResultBuilder.setInsecure(true);
|
||||
}
|
||||
|
||||
@@ -850,8 +863,8 @@ public class PgpDecryptVerify extends BaseOperation<PgpDecryptVerifyInputParcel>
|
||||
// The MDC packet can be stripped by an attacker!
|
||||
Log.d(Constants.TAG, "MDC fail");
|
||||
if (!signatureResultBuilder.isValidSignature()) {
|
||||
log.add(LogType.MSG_DC_ERROR_INTEGRITY_MISSING, indent);
|
||||
decryptionResult.setResult(OpenPgpDecryptionResult.RESULT_INSECURE);
|
||||
log.add(LogType.MSG_DC_INSECURE_MDC_MISSING, indent);
|
||||
decryptionResultBuilder.setInsecure(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -864,7 +877,7 @@ public class PgpDecryptVerify extends BaseOperation<PgpDecryptVerifyInputParcel>
|
||||
result.setCachedCryptoInputParcel(cryptoInput);
|
||||
result.setSignatureResult(signatureResultBuilder.build());
|
||||
result.setCharset(charset);
|
||||
result.setDecryptionResult(decryptionResult);
|
||||
result.setDecryptionResult(decryptionResultBuilder.build());
|
||||
result.setDecryptionMetadata(metadata);
|
||||
return result;
|
||||
|
||||
@@ -921,7 +934,7 @@ public class PgpDecryptVerify extends BaseOperation<PgpDecryptVerifyInputParcel>
|
||||
return new DecryptVerifyResult(DecryptVerifyResult.RESULT_ERROR, log);
|
||||
}
|
||||
|
||||
PGPSignature signature = processPGPSignatureList(sigList, signatureResultBuilder);
|
||||
PGPSignature signature = processPGPSignatureList(sigList, signatureResultBuilder, log, indent);
|
||||
|
||||
if (signature != null) {
|
||||
try {
|
||||
@@ -954,8 +967,8 @@ public class PgpDecryptVerify extends BaseOperation<PgpDecryptVerifyInputParcel>
|
||||
}
|
||||
|
||||
// check for insecure hash algorithms
|
||||
if (!PgpConstants.sHashAlgorithmsWhitelist.contains(signature.getHashAlgorithm())) {
|
||||
log.add(LogType.MSG_DC_ERROR_UNSUPPORTED_HASH_ALGO, indent + 1);
|
||||
if (!PgpSecurityConstants.isSecureHashAlgorithm(signature.getHashAlgorithm())) {
|
||||
log.add(LogType.MSG_DC_INSECURE_HASH_ALGO, indent + 1);
|
||||
signatureResultBuilder.setInsecure(true);
|
||||
}
|
||||
|
||||
@@ -1013,7 +1026,7 @@ public class PgpDecryptVerify extends BaseOperation<PgpDecryptVerifyInputParcel>
|
||||
return new DecryptVerifyResult(DecryptVerifyResult.RESULT_ERROR, log);
|
||||
}
|
||||
|
||||
PGPSignature signature = processPGPSignatureList(sigList, signatureResultBuilder);
|
||||
PGPSignature signature = processPGPSignatureList(sigList, signatureResultBuilder, log, indent);
|
||||
|
||||
if (signature != null) {
|
||||
updateProgress(R.string.progress_reading_data, 60, 100);
|
||||
@@ -1056,8 +1069,8 @@ public class PgpDecryptVerify extends BaseOperation<PgpDecryptVerifyInputParcel>
|
||||
}
|
||||
|
||||
// check for insecure hash algorithms
|
||||
if (!PgpConstants.sHashAlgorithmsWhitelist.contains(signature.getHashAlgorithm())) {
|
||||
log.add(LogType.MSG_DC_ERROR_UNSUPPORTED_HASH_ALGO, indent + 1);
|
||||
if (!PgpSecurityConstants.isSecureHashAlgorithm(signature.getHashAlgorithm())) {
|
||||
log.add(LogType.MSG_DC_INSECURE_HASH_ALGO, indent + 1);
|
||||
signatureResultBuilder.setInsecure(true);
|
||||
}
|
||||
|
||||
@@ -1076,7 +1089,8 @@ public class PgpDecryptVerify extends BaseOperation<PgpDecryptVerifyInputParcel>
|
||||
}
|
||||
|
||||
private PGPSignature processPGPSignatureList(
|
||||
PGPSignatureList sigList, OpenPgpSignatureResultBuilder signatureResultBuilder)
|
||||
PGPSignatureList sigList, OpenPgpSignatureResultBuilder signatureResultBuilder,
|
||||
OperationLog log, int indent)
|
||||
throws PGPException {
|
||||
CanonicalizedPublicKeyRing signingRing = null;
|
||||
CanonicalizedPublicKey signingKey = null;
|
||||
@@ -1118,6 +1132,13 @@ public class PgpDecryptVerify extends BaseOperation<PgpDecryptVerifyInputParcel>
|
||||
}
|
||||
}
|
||||
|
||||
// check for insecure signing key
|
||||
// TODO: checks on signingRing ?
|
||||
if (signingKey != null && ! PgpSecurityConstants.isSecureKey(signingKey)) {
|
||||
log.add(LogType.MSG_DC_INSECURE_KEY, indent + 1);
|
||||
signatureResultBuilder.setInsecure(true);
|
||||
}
|
||||
|
||||
return signature;
|
||||
}
|
||||
|
||||
|
||||
@@ -316,14 +316,14 @@ public class PgpKeyOperation {
|
||||
|
||||
// Build key encrypter and decrypter based on passphrase
|
||||
PGPDigestCalculator encryptorHashCalc = new JcaPGPDigestCalculatorProviderBuilder()
|
||||
.build().get(PgpConstants.SECRET_KEY_ENCRYPTOR_HASH_ALGO);
|
||||
.build().get(PgpSecurityConstants.SECRET_KEY_ENCRYPTOR_HASH_ALGO);
|
||||
PBESecretKeyEncryptor keyEncryptor = new JcePBESecretKeyEncryptorBuilder(
|
||||
PgpConstants.SECRET_KEY_ENCRYPTOR_SYMMETRIC_ALGO,
|
||||
encryptorHashCalc, PgpConstants.SECRET_KEY_ENCRYPTOR_S2K_COUNT)
|
||||
PgpSecurityConstants.SECRET_KEY_ENCRYPTOR_SYMMETRIC_ALGO,
|
||||
encryptorHashCalc, PgpSecurityConstants.SECRET_KEY_ENCRYPTOR_S2K_COUNT)
|
||||
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build("".toCharArray());
|
||||
|
||||
PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder()
|
||||
.build().get(PgpConstants.SECRET_KEY_SIGNATURE_CHECKSUM_HASH_ALGO);
|
||||
.build().get(PgpSecurityConstants.SECRET_KEY_SIGNATURE_CHECKSUM_HASH_ALGO);
|
||||
PGPSecretKey masterSecretKey = new PGPSecretKey(keyPair.getPrivateKey(), keyPair.getPublicKey(),
|
||||
sha1Calc, true, keyEncryptor);
|
||||
|
||||
@@ -1021,15 +1021,15 @@ public class PgpKeyOperation {
|
||||
PGPSecretKey sKey; {
|
||||
// Build key encrypter and decrypter based on passphrase
|
||||
PGPDigestCalculator encryptorHashCalc = new JcaPGPDigestCalculatorProviderBuilder()
|
||||
.build().get(PgpConstants.SECRET_KEY_ENCRYPTOR_HASH_ALGO);
|
||||
.build().get(PgpSecurityConstants.SECRET_KEY_ENCRYPTOR_HASH_ALGO);
|
||||
PBESecretKeyEncryptor keyEncryptor = new JcePBESecretKeyEncryptorBuilder(
|
||||
PgpConstants.SECRET_KEY_ENCRYPTOR_SYMMETRIC_ALGO, encryptorHashCalc,
|
||||
PgpConstants.SECRET_KEY_ENCRYPTOR_S2K_COUNT)
|
||||
PgpSecurityConstants.SECRET_KEY_ENCRYPTOR_SYMMETRIC_ALGO, encryptorHashCalc,
|
||||
PgpSecurityConstants.SECRET_KEY_ENCRYPTOR_S2K_COUNT)
|
||||
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
|
||||
cryptoInput.getPassphrase().getCharArray());
|
||||
|
||||
PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder()
|
||||
.build().get(PgpConstants.SECRET_KEY_SIGNATURE_CHECKSUM_HASH_ALGO);
|
||||
.build().get(PgpSecurityConstants.SECRET_KEY_SIGNATURE_CHECKSUM_HASH_ALGO);
|
||||
sKey = new PGPSecretKey(keyPair.getPrivateKey(), pKey, sha1Calc, false, keyEncryptor);
|
||||
}
|
||||
|
||||
@@ -1206,7 +1206,7 @@ public class PgpKeyOperation {
|
||||
// add packet with EMPTY notation data (updates old one, but will be stripped later)
|
||||
PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
|
||||
masterPrivateKey.getPublicKeyPacket().getAlgorithm(),
|
||||
PgpConstants.SECRET_KEY_BINDING_SIGNATURE_HASH_ALGO)
|
||||
PgpSecurityConstants.SECRET_KEY_BINDING_SIGNATURE_HASH_ALGO)
|
||||
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
|
||||
PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
|
||||
{ // set subpackets
|
||||
@@ -1233,7 +1233,7 @@ public class PgpKeyOperation {
|
||||
// add packet with "pin" notation data
|
||||
PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
|
||||
masterPrivateKey.getPublicKeyPacket().getAlgorithm(),
|
||||
PgpConstants.SECRET_KEY_BINDING_SIGNATURE_HASH_ALGO)
|
||||
PgpSecurityConstants.SECRET_KEY_BINDING_SIGNATURE_HASH_ALGO)
|
||||
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
|
||||
PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
|
||||
{ // set subpackets
|
||||
@@ -1280,13 +1280,13 @@ public class PgpKeyOperation {
|
||||
OperationLog log, int indent) throws PGPException {
|
||||
|
||||
PGPDigestCalculator encryptorHashCalc = new JcaPGPDigestCalculatorProviderBuilder().build()
|
||||
.get(PgpConstants.SECRET_KEY_ENCRYPTOR_HASH_ALGO);
|
||||
.get(PgpSecurityConstants.SECRET_KEY_ENCRYPTOR_HASH_ALGO);
|
||||
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
|
||||
Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.getCharArray());
|
||||
// Build key encryptor based on new passphrase
|
||||
PBESecretKeyEncryptor keyEncryptorNew = new JcePBESecretKeyEncryptorBuilder(
|
||||
PgpConstants.SECRET_KEY_ENCRYPTOR_SYMMETRIC_ALGO, encryptorHashCalc,
|
||||
PgpConstants.SECRET_KEY_ENCRYPTOR_S2K_COUNT)
|
||||
PgpSecurityConstants.SECRET_KEY_ENCRYPTOR_SYMMETRIC_ALGO, encryptorHashCalc,
|
||||
PgpSecurityConstants.SECRET_KEY_ENCRYPTOR_S2K_COUNT)
|
||||
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(newPassphrase.getCharArray());
|
||||
|
||||
// noinspection unchecked
|
||||
@@ -1440,13 +1440,13 @@ public class PgpKeyOperation {
|
||||
if (divertToCard) {
|
||||
// use synchronous "NFC based" SignerBuilder
|
||||
builder = new NfcSyncPGPContentSignerBuilder(
|
||||
pKey.getAlgorithm(), PgpConstants.SECRET_KEY_BINDING_SIGNATURE_HASH_ALGO,
|
||||
pKey.getAlgorithm(), PgpSecurityConstants.SECRET_KEY_BINDING_SIGNATURE_HASH_ALGO,
|
||||
pKey.getKeyID(), cryptoInput.getCryptoData())
|
||||
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
|
||||
} else {
|
||||
// content signer based on signing key algorithm and chosen hash algorithm
|
||||
builder = new JcaPGPContentSignerBuilder(
|
||||
pKey.getAlgorithm(), PgpConstants.SECRET_KEY_BINDING_SIGNATURE_HASH_ALGO)
|
||||
pKey.getAlgorithm(), PgpSecurityConstants.SECRET_KEY_BINDING_SIGNATURE_HASH_ALGO)
|
||||
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
|
||||
}
|
||||
|
||||
@@ -1472,11 +1472,11 @@ public class PgpKeyOperation {
|
||||
*/
|
||||
/* non-critical subpackets: */
|
||||
hashedPacketsGen.setPreferredSymmetricAlgorithms(false,
|
||||
PgpConstants.PREFERRED_SYMMETRIC_ALGORITHMS);
|
||||
PgpSecurityConstants.PREFERRED_SYMMETRIC_ALGORITHMS);
|
||||
hashedPacketsGen.setPreferredHashAlgorithms(false,
|
||||
PgpConstants.PREFERRED_HASH_ALGORITHMS);
|
||||
PgpSecurityConstants.PREFERRED_HASH_ALGORITHMS);
|
||||
hashedPacketsGen.setPreferredCompressionAlgorithms(false,
|
||||
PgpConstants.PREFERRED_COMPRESSION_ALGORITHMS);
|
||||
PgpSecurityConstants.PREFERRED_COMPRESSION_ALGORITHMS);
|
||||
hashedPacketsGen.setPrimaryUserID(false, primary);
|
||||
|
||||
/* critical subpackets: we consider those important for a modern pgp implementation */
|
||||
|
||||
@@ -0,0 +1,282 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.sufficientlysecure.keychain.pgp;
|
||||
|
||||
import org.spongycastle.asn1.nist.NISTNamedCurves;
|
||||
import org.spongycastle.bcpg.CompressionAlgorithmTags;
|
||||
import org.spongycastle.bcpg.HashAlgorithmTags;
|
||||
import org.spongycastle.bcpg.PublicKeyAlgorithmTags;
|
||||
import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* NIST requirements for 2011-2030 (http://www.keylength.com/en/4/):
|
||||
* - RSA: 2048 bit
|
||||
* - ECC: 224 bit
|
||||
* - Symmetric: 3TDEA
|
||||
* - Digital Signature (hash A): SHA-224 - SHA-512
|
||||
*
|
||||
* Extreme Decisions for Yahoo's End-to-End:
|
||||
* https://github.com/yahoo/end-to-end/issues/31
|
||||
* https://gist.github.com/coruus/68a8c65571e2b4225a69
|
||||
*/
|
||||
public class PgpSecurityConstants {
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
* 1. Check binding signatures for requirements on import! throw out binding signatures with insecure
|
||||
* signatures (bit length, hash algo)
|
||||
*
|
||||
* - put checks for curve OIDs and algorithm tags into import instead of PgpDecryptVerify?
|
||||
* - check signingRing in PgpDecryptVerify?
|
||||
* - ECC checks https://tools.ietf.org/html/rfc6637#section-13
|
||||
* - check encryption algo used for encrypting secret keys?
|
||||
* - check S2K security?
|
||||
* - check for min rsa/dsa/elgamal/ecc requirements in key creation backend
|
||||
*/
|
||||
|
||||
/**
|
||||
* Whitelist of accepted symmetric encryption algorithms
|
||||
* all other algorithms are rejected with OpenPgpDecryptionResult.RESULT_INSECURE
|
||||
*/
|
||||
private static HashSet<Integer> sSymmetricAlgorithmsWhitelist = new HashSet<>();
|
||||
static {
|
||||
// General remarks: We try to keep the whitelist short to reduce attack surface
|
||||
// TODO: block IDEA?: Bad key schedule (weak keys), implementation difficulties (easy to make errors)
|
||||
sSymmetricAlgorithmsWhitelist.add(SymmetricKeyAlgorithmTags.IDEA);
|
||||
sSymmetricAlgorithmsWhitelist.add(SymmetricKeyAlgorithmTags.TRIPLE_DES); // a MUST in RFC
|
||||
sSymmetricAlgorithmsWhitelist.add(SymmetricKeyAlgorithmTags.CAST5); // default in many gpg, pgp versions, 128 bit key
|
||||
// BLOWFISH: Twofish is the successor
|
||||
// SAFER: not used widely
|
||||
// DES: < 128 bit security
|
||||
sSymmetricAlgorithmsWhitelist.add(SymmetricKeyAlgorithmTags.AES_128);
|
||||
sSymmetricAlgorithmsWhitelist.add(SymmetricKeyAlgorithmTags.AES_192);
|
||||
sSymmetricAlgorithmsWhitelist.add(SymmetricKeyAlgorithmTags.AES_256);
|
||||
sSymmetricAlgorithmsWhitelist.add(SymmetricKeyAlgorithmTags.TWOFISH); // 128 bit
|
||||
// CAMELLIA_128: not used widely
|
||||
// CAMELLIA_192: not used widely
|
||||
// CAMELLIA_256: not used widely
|
||||
}
|
||||
|
||||
public static boolean isSecureSymmetricAlgorithm(int id) {
|
||||
return sSymmetricAlgorithmsWhitelist.contains(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whitelist of accepted hash algorithms
|
||||
* all other algorithms are rejected with OpenPgpSignatureResult.RESULT_INSECURE
|
||||
*
|
||||
* coorus:
|
||||
* Implementations SHOULD use SHA-512 for RSA or DSA signatures. They SHOULD NOT use SHA-384.
|
||||
* ((cite to affine padding attacks; unproven status of RSA-PKCSv15))
|
||||
*
|
||||
* Implementations MUST NOT sign SHA-224 hashes. They SHOULD NOT accept signatures over SHA-224 hashes.
|
||||
* ((collision resistance of 112-bits))
|
||||
* Implementations SHOULD NOT sign SHA-256 hashes. They MUST NOT default to signing SHA-256 hashes.
|
||||
*/
|
||||
private static HashSet<Integer> sHashAlgorithmsWhitelist = new HashSet<>();
|
||||
static {
|
||||
// MD5: broken
|
||||
// SHA1: broken
|
||||
// RIPEMD160: same security properties as SHA1
|
||||
// DOUBLE_SHA: not used widely
|
||||
// MD2: not used widely
|
||||
// TIGER_192: not used widely
|
||||
// HAVAL_5_160: not used widely
|
||||
sHashAlgorithmsWhitelist.add(HashAlgorithmTags.SHA256); // compatibility for old Mailvelope versions
|
||||
sHashAlgorithmsWhitelist.add(HashAlgorithmTags.SHA384);
|
||||
sHashAlgorithmsWhitelist.add(HashAlgorithmTags.SHA512);
|
||||
// SHA224: Not used widely, Yahoo argues against it
|
||||
}
|
||||
|
||||
public static boolean isSecureHashAlgorithm(int id) {
|
||||
return sHashAlgorithmsWhitelist.contains(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whitelist of accepted asymmetric algorithms in switch statement
|
||||
* all other algorithms are rejected with OpenPgpSignatureResult.RESULT_INSECURE or
|
||||
* OpenPgpDecryptionResult.RESULT_INSECURE
|
||||
*
|
||||
* REASON:
|
||||
* Don't allow ELGAMAL_GENERAL (20), reason in RFC
|
||||
*
|
||||
* coorus:
|
||||
* Implementations MUST NOT accept, or treat any signature as valid, by an RSA key with
|
||||
* bitlength less than 1023 bits.
|
||||
* Implementations MUST NOT accept any RSA keys with bitlength less than 2047 bits after January 1, 2016.
|
||||
*/
|
||||
private static HashSet<String> sCurveWhitelist = new HashSet<>();
|
||||
static {
|
||||
sCurveWhitelist.add(NISTNamedCurves.getOID("P-256").getId());
|
||||
sCurveWhitelist.add(NISTNamedCurves.getOID("P-384").getId());
|
||||
sCurveWhitelist.add(NISTNamedCurves.getOID("P-521").getId());
|
||||
}
|
||||
|
||||
public static boolean isSecureKey(CanonicalizedPublicKey key) {
|
||||
switch (key.getAlgorithm()) {
|
||||
case PublicKeyAlgorithmTags.RSA_GENERAL:
|
||||
case PublicKeyAlgorithmTags.RSA_ENCRYPT:
|
||||
case PublicKeyAlgorithmTags.RSA_SIGN: {
|
||||
return (key.getBitStrength() >= 2048);
|
||||
}
|
||||
|
||||
case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: {
|
||||
return (key.getBitStrength() >= 2048);
|
||||
}
|
||||
|
||||
case PublicKeyAlgorithmTags.DSA: {
|
||||
return (key.getBitStrength() >= 2048);
|
||||
}
|
||||
|
||||
case PublicKeyAlgorithmTags.ECDH:
|
||||
case PublicKeyAlgorithmTags.ECDSA: {
|
||||
return PgpSecurityConstants.sCurveWhitelist.contains(key.getCurveOid());
|
||||
}
|
||||
// ELGAMAL_GENERAL: Must not be used, use ELGAMAL_ENCRYPT
|
||||
// DIFFIE_HELLMAN: unsure
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* These array is written as a list of preferred encryption algorithms into keys created by us.
|
||||
* Other implementations may choose to honor this selection.
|
||||
* (Most preferred is first)
|
||||
*
|
||||
* REASON: See corresponding whitelist. AES received most cryptanalysis over the years
|
||||
* and is still secure!
|
||||
*/
|
||||
public static final int[] PREFERRED_SYMMETRIC_ALGORITHMS = new int[]{
|
||||
SymmetricKeyAlgorithmTags.AES_256,
|
||||
SymmetricKeyAlgorithmTags.AES_192,
|
||||
SymmetricKeyAlgorithmTags.AES_128,
|
||||
};
|
||||
|
||||
/**
|
||||
* These array is written as a list of preferred hash algorithms into keys created by us.
|
||||
* Other implementations may choose to honor this selection.
|
||||
* (Most preferred is first)
|
||||
*
|
||||
* REASON: See corresponding whitelist. If possible use SHA-512, this is state of the art!
|
||||
*/
|
||||
public static final int[] PREFERRED_HASH_ALGORITHMS = new int[]{
|
||||
HashAlgorithmTags.SHA512,
|
||||
};
|
||||
|
||||
/**
|
||||
* These array is written as a list of preferred compression algorithms into keys created by us.
|
||||
* Other implementations may choose to honor this selection.
|
||||
* (Most preferred is first)
|
||||
*
|
||||
* REASON: See DEFAULT_COMPRESSION_ALGORITHM
|
||||
*/
|
||||
public static final int[] PREFERRED_COMPRESSION_ALGORITHMS = new int[]{
|
||||
CompressionAlgorithmTags.ZIP,
|
||||
};
|
||||
|
||||
/**
|
||||
* Hash algorithm used to certify public keys
|
||||
*/
|
||||
public static final int CERTIFY_HASH_ALGO = HashAlgorithmTags.SHA512;
|
||||
|
||||
|
||||
/**
|
||||
* Always use AES-256! We always ignore the preferred encryption algos of the recipient!
|
||||
*
|
||||
* coorus:
|
||||
* Implementations SHOULD ignore the symmetric algorithm preferences of a recipient's public key;
|
||||
* in particular, implementations MUST NOT choose an algorithm forbidden by this
|
||||
* document because a recipient prefers it.
|
||||
*
|
||||
* NEEDCITE downgrade attacks on TLS, other protocols
|
||||
*/
|
||||
public static final int DEFAULT_SYMMETRIC_ALGORITHM = SymmetricKeyAlgorithmTags.AES_256;
|
||||
|
||||
public interface OpenKeychainSymmetricKeyAlgorithmTags extends SymmetricKeyAlgorithmTags {
|
||||
int USE_DEFAULT = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Always use SHA-512! We always ignore the preferred hash algos of the recipient!
|
||||
*
|
||||
* coorus:
|
||||
* Implementations MUST ignore the hash algorithm preferences of a recipient when signing
|
||||
* a message to a recipient. The difficulty of forging a signature under a given key,
|
||||
* using generic attacks on hash functions, is the difficulty of the weakest hash signed by that key.
|
||||
*
|
||||
* Implementations MUST default to using SHA-512 for RSA signatures,
|
||||
*
|
||||
* and either SHA-512 or the matched instance of SHA-2 for ECDSA signatures.
|
||||
* TODO: Ed25519
|
||||
* CITE: zooko's hash function table CITE: distinguishers on SHA-256
|
||||
*/
|
||||
public static final int DEFAULT_HASH_ALGORITHM = HashAlgorithmTags.SHA512;
|
||||
|
||||
public interface OpenKeychainHashAlgorithmTags extends HashAlgorithmTags {
|
||||
int USE_DEFAULT = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compression is disabled by default.
|
||||
*
|
||||
* The default compression algorithm is only used if explicitly enabled in the activity's
|
||||
* overflow menu or via the OpenPGP API's extra OpenPgpApi.EXTRA_ENABLE_COMPRESSION
|
||||
*
|
||||
* REASON: Enabling compression can lead to a sidechannel. Consider a voting that is done via
|
||||
* OpenPGP. Compression can lead to different ciphertext lengths based on the user's voting.
|
||||
* This has happened in a voting done by Wikipedia (Google it).
|
||||
*
|
||||
* ZLIB: the format provides no benefits over DEFLATE, and is more malleable
|
||||
* BZIP2: very slow
|
||||
*/
|
||||
public static final int DEFAULT_COMPRESSION_ALGORITHM = CompressionAlgorithmTags.ZIP;
|
||||
|
||||
public interface OpenKeychainCompressionAlgorithmTags extends CompressionAlgorithmTags {
|
||||
int USE_DEFAULT = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: s2kcount is a number between 0 and 0xff that controls the
|
||||
* number of times to iterate the password hash before use. More
|
||||
* iterations are useful against offline attacks, as it takes more
|
||||
* time to check each password. The actual number of iterations is
|
||||
* rather complex, and also depends on the hash function in use.
|
||||
* Refer to Section 3.7.1.3 in rfc4880.txt. Bigger numbers give
|
||||
* you more iterations. As a rough rule of thumb, when using
|
||||
* SHA256 as the hashing function, 0x10 gives you about 64
|
||||
* iterations, 0x20 about 128, 0x30 about 256 and so on till 0xf0,
|
||||
* or about 1 million iterations. The maximum you can go to is
|
||||
* 0xff, or about 2 million iterations.
|
||||
* from http://kbsriram.com/2013/01/generating-rsa-keys-with-bouncycastle.html
|
||||
*
|
||||
* Bouncy Castle default: 0x60
|
||||
* kbsriram proposes: 0xc0
|
||||
* Yahoo's End-to-End: 96 (65536 iterations) (https://github.com/yahoo/end-to-end/blob/master/src/javascript/crypto/e2e/openpgp/keyring.js)
|
||||
*/
|
||||
public static final int SECRET_KEY_ENCRYPTOR_S2K_COUNT = 96;
|
||||
public static final int SECRET_KEY_ENCRYPTOR_HASH_ALGO = HashAlgorithmTags.SHA512;
|
||||
public static final int SECRET_KEY_ENCRYPTOR_SYMMETRIC_ALGO = SymmetricKeyAlgorithmTags.AES_256;
|
||||
public static final int SECRET_KEY_BINDING_SIGNATURE_HASH_ALGO = HashAlgorithmTags.SHA512;
|
||||
// NOTE: only SHA1 is supported for key checksum calculations in OpenPGP,
|
||||
// see http://tools.ietf.org/html/rfc488 0#section-5.5.3
|
||||
public static final int SECRET_KEY_SIGNATURE_CHECKSUM_HASH_ALGO = HashAlgorithmTags.SHA1;
|
||||
|
||||
}
|
||||
@@ -33,10 +33,10 @@ public class PgpSignEncryptInputParcel implements Parcelable {
|
||||
protected int mCompressionAlgorithm = CompressionAlgorithmTags.UNCOMPRESSED;
|
||||
protected long[] mEncryptionMasterKeyIds = null;
|
||||
protected Passphrase mSymmetricPassphrase = null;
|
||||
protected int mSymmetricEncryptionAlgorithm = PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_DEFAULT;
|
||||
protected int mSymmetricEncryptionAlgorithm = PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_DEFAULT;
|
||||
protected long mSignatureMasterKeyId = Constants.key.none;
|
||||
protected Long mSignatureSubKeyId = null;
|
||||
protected int mSignatureHashAlgorithm = PgpConstants.OpenKeychainHashAlgorithmTags.USE_DEFAULT;
|
||||
protected int mSignatureHashAlgorithm = PgpSecurityConstants.OpenKeychainHashAlgorithmTags.USE_DEFAULT;
|
||||
protected long mAdditionalEncryptId = Constants.key.none;
|
||||
protected boolean mFailOnMissingEncryptionKeyIds = false;
|
||||
protected String mCharset;
|
||||
|
||||
@@ -62,7 +62,6 @@ import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.SignatureException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
@@ -228,8 +227,8 @@ public class PgpSignEncryptOperation extends BaseOperation {
|
||||
|
||||
// Use requested hash algo
|
||||
int requestedAlgorithm = input.getSignatureHashAlgorithm();
|
||||
if (requestedAlgorithm == PgpConstants.OpenKeychainHashAlgorithmTags.USE_DEFAULT) {
|
||||
input.setSignatureHashAlgorithm(PgpConstants.DEFAULT_HASH_ALGORITHM);
|
||||
if (requestedAlgorithm == PgpSecurityConstants.OpenKeychainHashAlgorithmTags.USE_DEFAULT) {
|
||||
input.setSignatureHashAlgorithm(PgpSecurityConstants.DEFAULT_HASH_ALGORITHM);
|
||||
}
|
||||
}
|
||||
updateProgress(R.string.progress_preparing_streams, 2, 100);
|
||||
@@ -240,8 +239,8 @@ public class PgpSignEncryptOperation extends BaseOperation {
|
||||
|
||||
// Use requested encryption algo
|
||||
int algo = input.getSymmetricEncryptionAlgorithm();
|
||||
if (algo == PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_DEFAULT) {
|
||||
algo = PgpConstants.DEFAULT_SYMMETRIC_ALGORITHM;
|
||||
if (algo == PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_DEFAULT) {
|
||||
algo = PgpSecurityConstants.DEFAULT_SYMMETRIC_ALGORITHM;
|
||||
}
|
||||
// has Integrity packet enabled!
|
||||
JcePGPDataEncryptorBuilder encryptorBuilder =
|
||||
@@ -337,8 +336,8 @@ public class PgpSignEncryptOperation extends BaseOperation {
|
||||
|
||||
// Use preferred compression algo
|
||||
int algo = input.getCompressionAlgorithm();
|
||||
if (algo == PgpConstants.OpenKeychainCompressionAlgorithmTags.USE_DEFAULT) {
|
||||
algo = PgpConstants.DEFAULT_COMPRESSION_ALGORITHM;
|
||||
if (algo == PgpSecurityConstants.OpenKeychainCompressionAlgorithmTags.USE_DEFAULT) {
|
||||
algo = PgpSecurityConstants.DEFAULT_COMPRESSION_ALGORITHM;
|
||||
}
|
||||
compressGen = new PGPCompressedDataGenerator(algo);
|
||||
bcpgOut = new BCPGOutputStream(compressGen.open(encryptionOut));
|
||||
|
||||
@@ -211,12 +211,19 @@ public class UncachedPublicKey {
|
||||
return getAlgorithm() == PGPPublicKey.ELGAMAL_ENCRYPT;
|
||||
}
|
||||
|
||||
public boolean isRSA() {
|
||||
return getAlgorithm() == PGPPublicKey.RSA_GENERAL
|
||||
|| getAlgorithm() == PGPPublicKey.RSA_ENCRYPT
|
||||
|| getAlgorithm() == PGPPublicKey.RSA_SIGN;
|
||||
}
|
||||
|
||||
public boolean isDSA() {
|
||||
return getAlgorithm() == PGPPublicKey.DSA;
|
||||
}
|
||||
|
||||
public boolean isEC() {
|
||||
return getAlgorithm() == PGPPublicKey.ECDH || getAlgorithm() == PGPPublicKey.ECDSA;
|
||||
return getAlgorithm() == PGPPublicKey.ECDH
|
||||
|| getAlgorithm() == PGPPublicKey.ECDSA;
|
||||
}
|
||||
|
||||
public byte[] getFingerprint() {
|
||||
|
||||
@@ -45,7 +45,7 @@ import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey;
|
||||
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType;
|
||||
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing;
|
||||
import org.sufficientlysecure.keychain.pgp.KeyRing;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpConstants;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpSecurityConstants;
|
||||
import org.sufficientlysecure.keychain.pgp.Progressable;
|
||||
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
|
||||
import org.sufficientlysecure.keychain.pgp.UncachedPublicKey;
|
||||
@@ -1434,9 +1434,9 @@ public class ProviderHelper {
|
||||
// DEPRECATED and thus hardcoded
|
||||
values.put(KeychainContract.ApiAccounts.COMPRESSION, CompressionAlgorithmTags.ZLIB);
|
||||
values.put(KeychainContract.ApiAccounts.ENCRYPTION_ALGORITHM,
|
||||
PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_DEFAULT);
|
||||
PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_DEFAULT);
|
||||
values.put(KeychainContract.ApiAccounts.HASH_ALORITHM,
|
||||
PgpConstants.OpenKeychainHashAlgorithmTags.USE_DEFAULT);
|
||||
PgpSecurityConstants.OpenKeychainHashAlgorithmTags.USE_DEFAULT);
|
||||
return values;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogEntryParcel;
|
||||
import org.sufficientlysecure.keychain.operations.results.PgpSignEncryptResult;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpConstants;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpSecurityConstants;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpSignEncryptInputParcel;
|
||||
@@ -248,7 +248,7 @@ public class OpenPgpService extends RemoteService {
|
||||
.setCleartextSignature(cleartextSign)
|
||||
.setDetachedSignature(!cleartextSign)
|
||||
.setVersionHeader(null)
|
||||
.setSignatureHashAlgorithm(PgpConstants.OpenKeychainHashAlgorithmTags.USE_DEFAULT);
|
||||
.setSignatureHashAlgorithm(PgpSecurityConstants.OpenKeychainHashAlgorithmTags.USE_DEFAULT);
|
||||
|
||||
Intent signKeyIdIntent = getSignKeyMasterId(data);
|
||||
// NOTE: Fallback to return account settings (Old API)
|
||||
@@ -359,9 +359,9 @@ public class OpenPgpService extends RemoteService {
|
||||
boolean enableCompression = data.getBooleanExtra(OpenPgpApi.EXTRA_ENABLE_COMPRESSION, true);
|
||||
int compressionId;
|
||||
if (enableCompression) {
|
||||
compressionId = PgpConstants.OpenKeychainCompressionAlgorithmTags.USE_DEFAULT;
|
||||
compressionId = PgpSecurityConstants.OpenKeychainCompressionAlgorithmTags.USE_DEFAULT;
|
||||
} else {
|
||||
compressionId = PgpConstants.OpenKeychainCompressionAlgorithmTags.UNCOMPRESSED;
|
||||
compressionId = PgpSecurityConstants.OpenKeychainCompressionAlgorithmTags.UNCOMPRESSED;
|
||||
}
|
||||
|
||||
// first try to get key ids from non-ambiguous key id extra
|
||||
@@ -392,7 +392,7 @@ public class OpenPgpService extends RemoteService {
|
||||
pseInput.setEnableAsciiArmorOutput(asciiArmor)
|
||||
.setVersionHeader(null)
|
||||
.setCompressionAlgorithm(compressionId)
|
||||
.setSymmetricEncryptionAlgorithm(PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_DEFAULT)
|
||||
.setSymmetricEncryptionAlgorithm(PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_DEFAULT)
|
||||
.setEncryptionMasterKeyIds(keyIds)
|
||||
.setFailOnMissingEncryptionKeyIds(true);
|
||||
|
||||
@@ -421,7 +421,7 @@ public class OpenPgpService extends RemoteService {
|
||||
}
|
||||
|
||||
// sign and encrypt
|
||||
pseInput.setSignatureHashAlgorithm(PgpConstants.OpenKeychainHashAlgorithmTags.USE_DEFAULT)
|
||||
pseInput.setSignatureHashAlgorithm(PgpSecurityConstants.OpenKeychainHashAlgorithmTags.USE_DEFAULT)
|
||||
.setAdditionalEncryptId(signKeyId); // add sign key for encryption
|
||||
}
|
||||
|
||||
|
||||
@@ -50,12 +50,11 @@ import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.spongycastle.bcpg.CompressionAlgorithmTags;
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.operations.results.SignEncryptResult;
|
||||
import org.sufficientlysecure.keychain.pgp.KeyRing;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpConstants;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpSecurityConstants;
|
||||
import org.sufficientlysecure.keychain.pgp.SignEncryptParcel;
|
||||
import org.sufficientlysecure.keychain.provider.TemporaryStorageProvider;
|
||||
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
|
||||
@@ -554,17 +553,17 @@ public class EncryptFilesFragment
|
||||
|
||||
if (mUseCompression) {
|
||||
data.setCompressionAlgorithm(
|
||||
PgpConstants.OpenKeychainCompressionAlgorithmTags.USE_DEFAULT);
|
||||
PgpSecurityConstants.OpenKeychainCompressionAlgorithmTags.USE_DEFAULT);
|
||||
} else {
|
||||
data.setCompressionAlgorithm(
|
||||
PgpConstants.OpenKeychainCompressionAlgorithmTags.UNCOMPRESSED);
|
||||
PgpSecurityConstants.OpenKeychainCompressionAlgorithmTags.UNCOMPRESSED);
|
||||
}
|
||||
data.setHiddenRecipients(mHiddenRecipients);
|
||||
data.setEnableAsciiArmorOutput(mAfterEncryptAction == AfterEncryptAction.COPY || mUseArmor);
|
||||
data.setSymmetricEncryptionAlgorithm(
|
||||
PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_DEFAULT);
|
||||
PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_DEFAULT);
|
||||
data.setSignatureHashAlgorithm(
|
||||
PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_DEFAULT);
|
||||
PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_DEFAULT);
|
||||
|
||||
EncryptActivity encryptActivity = (EncryptActivity) getActivity();
|
||||
EncryptModeFragment modeFragment = encryptActivity.getModeFragment();
|
||||
|
||||
@@ -33,12 +33,11 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.spongycastle.bcpg.CompressionAlgorithmTags;
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.operations.results.SignEncryptResult;
|
||||
import org.sufficientlysecure.keychain.pgp.KeyRing;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpConstants;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpSecurityConstants;
|
||||
import org.sufficientlysecure.keychain.pgp.SignEncryptParcel;
|
||||
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
|
||||
import org.sufficientlysecure.keychain.ui.base.CachingCryptoOperationFragment;
|
||||
@@ -224,16 +223,16 @@ public class EncryptTextFragment
|
||||
|
||||
if (mUseCompression) {
|
||||
data.setCompressionAlgorithm(
|
||||
PgpConstants.OpenKeychainCompressionAlgorithmTags.USE_DEFAULT);
|
||||
PgpSecurityConstants.OpenKeychainCompressionAlgorithmTags.USE_DEFAULT);
|
||||
} else {
|
||||
data.setCompressionAlgorithm(
|
||||
PgpConstants.OpenKeychainCompressionAlgorithmTags.UNCOMPRESSED);
|
||||
PgpSecurityConstants.OpenKeychainCompressionAlgorithmTags.UNCOMPRESSED);
|
||||
}
|
||||
data.setHiddenRecipients(mHiddenRecipients);
|
||||
data.setSymmetricEncryptionAlgorithm(
|
||||
PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_DEFAULT);
|
||||
PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_DEFAULT);
|
||||
data.setSignatureHashAlgorithm(
|
||||
PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_DEFAULT);
|
||||
PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_DEFAULT);
|
||||
|
||||
// Always use armor for messages
|
||||
data.setEnableAsciiArmorOutput(true);
|
||||
|
||||
@@ -953,7 +953,7 @@
|
||||
<string name="msg_dc_clear_meta_size_unknown">Dateigröße unbekannt</string>
|
||||
<string name="msg_dc_clear_meta_time">Änderungszeit: %s</string>
|
||||
<string name="msg_dc_clear_signature_bad">Signaturprüfung NICHT OK!</string>
|
||||
<string name="msg_dc_error_unsupported_hash_algo">Nicht unterstützter und potentiell unsicherer Hash-Algorithmus!</string>
|
||||
<string name="msg_dc_insecure_hash_algo">Nicht unterstützter und potentiell unsicherer Hash-Algorithmus!</string>
|
||||
<string name="msg_dc_clear_signature_check">Signaturdaten werden überprüft</string>
|
||||
<string name="msg_dc_clear_signature_ok">Signaturprüfung OK</string>
|
||||
<string name="msg_dc_clear_signature">Speichere Signatur für später</string>
|
||||
@@ -962,7 +962,7 @@
|
||||
<string name="msg_dc_error_corrupt_data">Daten beschädigt!</string>
|
||||
<string name="msg_dc_error_extract_key">Unbekannter Fehler bei Schlüsselentsperrung!</string>
|
||||
<string name="msg_dc_error_integrity_check">Integritätsprüfungsfehler!</string>
|
||||
<string name="msg_dc_error_integrity_missing">Fehlende Integritätsprüfung Dies kann passieren, wenn die Verschlüsselungsanwendung veraltet ist oder durch einen Downgrade-Angriff.</string>
|
||||
<string name="msg_dc_insecure_mdc_missing">Fehlende Integritätsprüfung Dies kann passieren, wenn die Verschlüsselungsanwendung veraltet ist oder durch einen Downgrade-Angriff.</string>
|
||||
<string name="msg_dc_error_invalid_data">Kein gültiger OpenPGP-verschlüsselter oder -signierter Inhalt!</string>
|
||||
<string name="msg_dc_error_no_data">Keine verschlüsselten Daten in Datenstrom gefunden!</string>
|
||||
<string name="msg_dc_error_no_key">Keine verschlüsselten Daten mit bekanntem geheimen Schlüssel in Datenstrom gefunden!</string>
|
||||
@@ -981,7 +981,7 @@
|
||||
<string name="msg_dc_trail_sym">Anhang gefunden, symmetrisch verschlüsselte Daten</string>
|
||||
<string name="msg_dc_trail_unknown">Anhängende Daten unbekannter Art gefunden</string>
|
||||
<string name="msg_dc_unlocking">Geheimer Schlüssel wird entsperrt</string>
|
||||
<string name="msg_dc_old_symmetric_encryption_algo">Ein potentiell unsicherer Verschlüsselungsalgorithmus wurde verwendet!</string>
|
||||
<string name="msg_dc_insecure_symmetric_encryption_algo">Ein potentiell unsicherer Verschlüsselungsalgorithmus wurde verwendet!</string>
|
||||
<!--Messages for VerifySignedLiteralData operation-->
|
||||
<string name="msg_vl">Starte Signaturprüfung</string>
|
||||
<string name="msg_vl_error_no_siglist">Keine Signaturliste in signierten Literaldaten</string>
|
||||
|
||||
@@ -1007,7 +1007,7 @@
|
||||
<string name="msg_dc_clear_meta_size_unknown">Tamaño de fichero desconocido</string>
|
||||
<string name="msg_dc_clear_meta_time">Hora de la modificación: %s</string>
|
||||
<string name="msg_dc_clear_signature_bad">¡Comprobación de firma NO CORRECTA!</string>
|
||||
<string name="msg_dc_error_unsupported_hash_algo">¡Algoritmo de identificador criptográfico (hash) no soportado y potencialmente inseguro!</string>
|
||||
<string name="msg_dc_insecure_hash_algo">¡Algoritmo de identificador criptográfico (hash) no soportado y potencialmente inseguro!</string>
|
||||
<string name="msg_dc_clear_signature_check">Verificando datos de firma</string>
|
||||
<string name="msg_dc_clear_signature_ok">Comprobación de firma CORRECTA</string>
|
||||
<string name="msg_dc_clear_signature">Guardando datos de firma para más tarde</string>
|
||||
@@ -1016,7 +1016,7 @@
|
||||
<string name="msg_dc_error_corrupt_data">¡Los datos están corruptos!</string>
|
||||
<string name="msg_dc_error_extract_key">¡Error desconocido al desbloquear clave!</string>
|
||||
<string name="msg_dc_error_integrity_check">¡Error de comprobación de integridad!</string>
|
||||
<string name="msg_dc_error_integrity_missing">¡Verificación de integridad ausente! Esto puede ocurrir porque la aplicación de cifrado no está actualizada, o debido a un ataque desactualización.</string>
|
||||
<string name="msg_dc_insecure_mdc_missing">¡Verificación de integridad ausente! Esto puede ocurrir porque la aplicación de cifrado no está actualizada, o debido a un ataque desactualización.</string>
|
||||
<string name="msg_dc_error_invalid_data">¡No se encontraron datos firmados o cifrados con OpenPGP válidos!</string>
|
||||
<string name="msg_dc_error_io">¡Se encontró un error al leer los datos de entrada!</string>
|
||||
<string name="msg_dc_error_input">¡Error al abrir el flujo de datos de entrada!</string>
|
||||
@@ -1037,7 +1037,7 @@
|
||||
<string name="msg_dc_trail_sym">Se encontró huella, datos cifrados simétricamente</string>
|
||||
<string name="msg_dc_trail_unknown">Se encontró huella, datos de tipo desconocido</string>
|
||||
<string name="msg_dc_unlocking">Desbloqueando clave secreta (privada)</string>
|
||||
<string name="msg_dc_old_symmetric_encryption_algo">¡Se ha usado un algoritmo de cifrado potencialmente inseguro!</string>
|
||||
<string name="msg_dc_insecure_symmetric_encryption_algo">¡Se ha usado un algoritmo de cifrado potencialmente inseguro!</string>
|
||||
<!--Messages for VerifySignedLiteralData operation-->
|
||||
<string name="msg_vl">Comenzando comprobación de firma</string>
|
||||
<string name="msg_vl_error_no_siglist">No hay lista de firmas en los datos literales firmados</string>
|
||||
|
||||
@@ -841,7 +841,7 @@
|
||||
<string name="msg_dc_clear_meta_size_unknown">Agiri neurria ezezaguna da</string>
|
||||
<string name="msg_dc_clear_meta_time">Aldaketa ordua: %s</string>
|
||||
<string name="msg_dc_clear_signature_bad">Sinadura egiaztapena EZ ONGI!</string>
|
||||
<string name="msg_dc_error_unsupported_hash_algo">Hash algoritmo sostengatu gabea eta potentzialki segurtasun gabea!</string>
|
||||
<string name="msg_dc_insecure_hash_algo">Hash algoritmo sostengatu gabea eta potentzialki segurtasun gabea!</string>
|
||||
<string name="msg_dc_clear_signature_check">Sinadura datuak egiaztatzen</string>
|
||||
<string name="msg_dc_clear_signature_ok">Sinadura egiaztapena ONGI</string>
|
||||
<string name="msg_dc_clear_signature">Sinadura datuak gerorako gordetzen</string>
|
||||
@@ -864,7 +864,7 @@
|
||||
<string name="msg_dc">Dekriptaketa eragiketa abiatzen...</string>
|
||||
<string name="msg_dc_sym_skip">Datu simetrikoak ez daude ahalbidetuta, jauzi egiten...</string>
|
||||
<string name="msg_dc_unlocking">Giltza sekretua desblokeatzen</string>
|
||||
<string name="msg_dc_old_symmetric_encryption_algo">Potentzialki segurtasun gabea den enkriptaketa algoritmoa erabili da!</string>
|
||||
<string name="msg_dc_insecure_symmetric_encryption_algo">Potentzialki segurtasun gabea den enkriptaketa algoritmoa erabili da!</string>
|
||||
<!--Messages for VerifySignedLiteralData operation-->
|
||||
<string name="msg_vl">Sinadura egiaztapena abiatzen</string>
|
||||
<string name="msg_vl_error_wrong_key">Mezua ez dago giltza zuzenarekin sinatuta</string>
|
||||
|
||||
@@ -981,7 +981,7 @@
|
||||
<string name="msg_dc_clear_meta_size_unknown">La taille du fichier est inconnue</string>
|
||||
<string name="msg_dc_clear_meta_time">Heure de modification : %s</string>
|
||||
<string name="msg_dc_clear_signature_bad">La vérification de la signature n\'est PAS CORRECTE !</string>
|
||||
<string name="msg_dc_error_unsupported_hash_algo">Algorithme de hachage non pris en charge et potentiellement non sécurisé ! </string>
|
||||
<string name="msg_dc_insecure_hash_algo">Algorithme de hachage non pris en charge et potentiellement non sécurisé ! </string>
|
||||
<string name="msg_dc_clear_signature_check">Vérification des données de signature</string>
|
||||
<string name="msg_dc_clear_signature_ok">La vérification de la signature OK</string>
|
||||
<string name="msg_dc_clear_signature">Enregistrement des données de signature pour plus tard</string>
|
||||
@@ -990,7 +990,7 @@
|
||||
<string name="msg_dc_error_corrupt_data"> Les données sont corrompues !</string>
|
||||
<string name="msg_dc_error_extract_key">Erreur inconnue de déverrouillage de la clef !</string>
|
||||
<string name="msg_dc_error_integrity_check">Erreur de vérification de l\'intégrité !</string>
|
||||
<string name="msg_dc_error_integrity_missing">Vérification de l\'intégrité absente ! Ceci peut arriver car l\'application n\'est pas à jour, ou à cause d\'une attaque par mise à niveau inférieur.</string>
|
||||
<string name="msg_dc_insecure_mdc_missing">Vérification de l\'intégrité absente ! Ceci peut arriver car l\'application n\'est pas à jour, ou à cause d\'une attaque par mise à niveau inférieur.</string>
|
||||
<string name="msg_dc_error_invalid_data">Aucune donnée OpenPGP valide chiffrée ou signée n\'a été trouvée !</string>
|
||||
<string name="msg_dc_error_no_data">Aucune donnée chiffrée n\'a été trouvée dans le flux !</string>
|
||||
<string name="msg_dc_error_no_key">Aucune donnée chiffrée avec une clef secrète connue n\'a été trouvée dans le flux !</string>
|
||||
@@ -1009,7 +1009,7 @@
|
||||
<string name="msg_dc_trail_sym">Des données traînantes chiffrées symétriquement ont été rencontrées</string>
|
||||
<string name="msg_dc_trail_unknown">Des données traînantes de type inconnu ont été rencontrées</string>
|
||||
<string name="msg_dc_unlocking">Déverrouillage de la clef secrète</string>
|
||||
<string name="msg_dc_old_symmetric_encryption_algo">Un algorithme de chiffrement possiblement non sécurisé à été utilisé !</string>
|
||||
<string name="msg_dc_insecure_symmetric_encryption_algo">Un algorithme de chiffrement possiblement non sécurisé à été utilisé !</string>
|
||||
<!--Messages for VerifySignedLiteralData operation-->
|
||||
<string name="msg_vl">Lancement de la vérification de la signature</string>
|
||||
<string name="msg_vl_error_no_siglist">Aucune liste de signatures dans les données littérales signées</string>
|
||||
|
||||
@@ -905,7 +905,7 @@
|
||||
<string name="msg_dc_clear_meta_size_unknown">ファイルサイズが不明</string>
|
||||
<string name="msg_dc_clear_meta_time">更新日時: %s</string>
|
||||
<string name="msg_dc_clear_signature_bad">署名の確認がOKではありません!</string>
|
||||
<string name="msg_dc_error_unsupported_hash_algo">サポート外かつセキュアでない可能性があるハッシュアルゴリズム!</string>
|
||||
<string name="msg_dc_insecure_hash_algo">サポート外かつセキュアでない可能性があるハッシュアルゴリズム!</string>
|
||||
<string name="msg_dc_clear_signature_check">署名データの検証中</string>
|
||||
<string name="msg_dc_clear_signature_ok">署名の確認はOKです</string>
|
||||
<string name="msg_dc_clear_signature">後程署名データを保存します</string>
|
||||
@@ -913,7 +913,7 @@
|
||||
<string name="msg_dc_error_bad_passphrase">鍵のロック解除エラー、パスフレーズに問題があります!</string>
|
||||
<string name="msg_dc_error_extract_key">鍵のロック解除で不明なエラー!</string>
|
||||
<string name="msg_dc_error_integrity_check">完全性チェックエラー!</string>
|
||||
<string name="msg_dc_error_integrity_missing">完全聖チェックの欠落!これは暗号化アプリケーションが期限切れになった場合、もしくは暗号強度低下攻撃がある場合に発生します。</string>
|
||||
<string name="msg_dc_insecure_mdc_missing">完全聖チェックの欠落!これは暗号化アプリケーションが期限切れになった場合、もしくは暗号強度低下攻撃がある場合に発生します。</string>
|
||||
<string name="msg_dc_error_invalid_data">正常な署名データが見付からなかった!</string>
|
||||
<string name="msg_dc_error_io">操作中にIO例外に当たりました!</string>
|
||||
<string name="msg_dc_error_no_data">ストリーム中に暗号化されたデータが見付からなかった!</string>
|
||||
@@ -933,7 +933,7 @@
|
||||
<string name="msg_dc_trail_sym">追跡で遭遇、対称暗号化されたデータ</string>
|
||||
<string name="msg_dc_trail_unknown">追跡で未知のタイプのデータに遭遇</string>
|
||||
<string name="msg_dc_unlocking">秘密鍵のロック解除</string>
|
||||
<string name="msg_dc_old_symmetric_encryption_algo">セキュアでない可能性がある暗号化アルゴリズムが利用されています!</string>
|
||||
<string name="msg_dc_insecure_symmetric_encryption_algo">セキュアでない可能性がある暗号化アルゴリズムが利用されています!</string>
|
||||
<!--Messages for VerifySignedLiteralData operation-->
|
||||
<string name="msg_vl">署名の確認開始</string>
|
||||
<string name="msg_vl_error_no_siglist">署名済み固定データに署名リストがありません</string>
|
||||
|
||||
@@ -1007,7 +1007,7 @@
|
||||
<string name="msg_dc_clear_meta_size_unknown">Bestandsgrootte onbekend</string>
|
||||
<string name="msg_dc_clear_meta_time">Wijzigingstijd: %s</string>
|
||||
<string name="msg_dc_clear_signature_bad">Ondertekeningscontrole NIET OKÉ!</string>
|
||||
<string name="msg_dc_error_unsupported_hash_algo">Niet ondersteund en mogelijk onveilig hash-algoritme!</string>
|
||||
<string name="msg_dc_insecure_hash_algo">Niet ondersteund en mogelijk onveilig hash-algoritme!</string>
|
||||
<string name="msg_dc_clear_signature_check">Bezig met verifiëren van ondertekeningsgegevens</string>
|
||||
<string name="msg_dc_clear_signature_ok">Ondertekeningscontrole OKÉ</string>
|
||||
<string name="msg_dc_clear_signature">Bezig met opslaan van ondertekeningsgegevens voor later</string>
|
||||
@@ -1016,7 +1016,7 @@
|
||||
<string name="msg_dc_error_corrupt_data">Gegevens zijn corrupt!</string>
|
||||
<string name="msg_dc_error_extract_key">Onbekende fout bij ontgrendelen van sleutel!</string>
|
||||
<string name="msg_dc_error_integrity_check">Fout bij integriteitscontrole!</string>
|
||||
<string name="msg_dc_error_integrity_missing">Integriteitscheck ontbreekt! Dit kan gebeuren omdat de versleutelingsapplicatie verouderd is, of door een downgrade-aanval.</string>
|
||||
<string name="msg_dc_insecure_mdc_missing">Integriteitscheck ontbreekt! Dit kan gebeuren omdat de versleutelingsapplicatie verouderd is, of door een downgrade-aanval.</string>
|
||||
<string name="msg_dc_error_invalid_data">Geen geldige OpenPGP-versleutelde of ondertekende inhoud gevonden!</string>
|
||||
<string name="msg_dc_error_no_data">Geen versleutelde gegevens gevonden!</string>
|
||||
<string name="msg_dc_error_no_key">Geen versleutelde gegevens met bekende geheime sleutel gevonden!</string>
|
||||
@@ -1035,7 +1035,7 @@
|
||||
<string name="msg_dc_trail_sym">Achterlopende, symmetrisch versleutelde gegevens tegengekomen</string>
|
||||
<string name="msg_dc_trail_unknown">Achterlopende gegevens van onbekend type tegengekomen</string>
|
||||
<string name="msg_dc_unlocking">Bezig met ontgrendelen van geheime sleutel</string>
|
||||
<string name="msg_dc_old_symmetric_encryption_algo">Mogelijk onveilig versleutelingsalgoritme gebruikt!</string>
|
||||
<string name="msg_dc_insecure_symmetric_encryption_algo">Mogelijk onveilig versleutelingsalgoritme gebruikt!</string>
|
||||
<!--Messages for VerifySignedLiteralData operation-->
|
||||
<string name="msg_vl">Ondertekeningscontrole wordt gestart</string>
|
||||
<string name="msg_vl_error_no_siglist">Geen ondertekeningslijst in ondertekende letterlijke gegevens</string>
|
||||
|
||||
@@ -726,7 +726,7 @@
|
||||
<string name="msg_dc_clear_decompress">Распаковка сжатых данных</string>
|
||||
<string name="msg_dc_clear_meta_size_unknown">Неизвестный размер файла</string>
|
||||
<string name="msg_dc_clear_signature_bad">Проверка подписи НЕ ПРОЙДЕНА!</string>
|
||||
<string name="msg_dc_error_unsupported_hash_algo">Неподдерживаемый, и потенциально небезопасный алгоритм хэширования!</string>
|
||||
<string name="msg_dc_insecure_hash_algo">Неподдерживаемый, и потенциально небезопасный алгоритм хэширования!</string>
|
||||
<string name="msg_dc_clear_signature_check">Проверка подписи данных</string>
|
||||
<string name="msg_dc_clear_signature_ok">Проверка подписи ПРОЙДЕНА</string>
|
||||
<string name="msg_dc_clear_signature">Сохранение данных подписи</string>
|
||||
@@ -737,7 +737,7 @@
|
||||
<string name="msg_dc_ok">Расшифрование/проверка закончена</string>
|
||||
<string name="msg_dc_pass_cached">Использование фразы-пароля из кэша</string>
|
||||
<string name="msg_dc_unlocking">Разблокировка секретного ключа</string>
|
||||
<string name="msg_dc_old_symmetric_encryption_algo">Был использован потенциально небезопасный алгоритм шифрования!</string>
|
||||
<string name="msg_dc_insecure_symmetric_encryption_algo">Был использован потенциально небезопасный алгоритм шифрования!</string>
|
||||
<!--Messages for VerifySignedLiteralData operation-->
|
||||
<string name="msg_vl_clear_signature_check">Проверка подписи данных</string>
|
||||
<string name="msg_vl_ok">ОК</string>
|
||||
|
||||
@@ -915,7 +915,7 @@
|
||||
<string name="msg_dc_error_bad_passphrase">Грешка откључавања кључа, погрешна лозинка!</string>
|
||||
<string name="msg_dc_error_extract_key">Непозната грешка откључавања кључа!</string>
|
||||
<string name="msg_dc_error_integrity_check">Грешка провере интегритета!</string>
|
||||
<string name="msg_dc_error_integrity_missing">Недостаје провера интегритета! Ово може да се деси ако је апликација за шифровање застарела, или услед напада старијег издања.</string>
|
||||
<string name="msg_dc_insecure_mdc_missing">Недостаје провера интегритета! Ово може да се деси ако је апликација за шифровање застарела, или услед напада старијег издања.</string>
|
||||
<string name="msg_dc_error_invalid_data">Нису нађени исправни подаци потписа!</string>
|
||||
<string name="msg_dc_error_io">Наиђох на У/И изузетак током радње!</string>
|
||||
<string name="msg_dc_error_no_data">Шифровани подаци нису нађени у току!</string>
|
||||
|
||||
@@ -1134,7 +1134,6 @@
|
||||
<string name="msg_dc_clear_meta_size_unknown">"File size is unknown"</string>
|
||||
<string name="msg_dc_clear_meta_time">"Modification time: %s"</string>
|
||||
<string name="msg_dc_clear_signature_bad">"Signature check NOT OK!"</string>
|
||||
<string name="msg_dc_error_unsupported_hash_algo">"Unsupported and potentially insecure hash algorithm!"</string>
|
||||
<string name="msg_dc_clear_signature_check">"Verifying signature data"</string>
|
||||
<string name="msg_dc_clear_signature_ok">"Signature check OK"</string>
|
||||
<string name="msg_dc_clear_signature">"Saving signature data for later"</string>
|
||||
@@ -1144,7 +1143,6 @@
|
||||
<string name="msg_dc_error_corrupt_data">"Data is corrupt!"</string>
|
||||
<string name="msg_dc_error_extract_key">"Unknown error unlocking key!"</string>
|
||||
<string name="msg_dc_error_integrity_check">"Integrity check error!"</string>
|
||||
<string name="msg_dc_error_integrity_missing">"Missing integrity check! This can happen because the encrypting application is out of date, or from a downgrade attack."</string>
|
||||
<string name="msg_dc_error_invalid_data">"No valid OpenPGP encrypted or signed data found!"</string>
|
||||
<string name="msg_dc_error_io">"Encountered an error reading input data!"</string>
|
||||
<string name="msg_dc_error_input">"Error opening input data stream!"</string>
|
||||
@@ -1165,7 +1163,10 @@
|
||||
<string name="msg_dc_trail_sym">"Encountered trailing, symmetrically encrypted data"</string>
|
||||
<string name="msg_dc_trail_unknown">"Encountered trailing data of unknown type"</string>
|
||||
<string name="msg_dc_unlocking">"Unlocking secret key"</string>
|
||||
<string name="msg_dc_old_symmetric_encryption_algo">"Insecure encryption algorithm has been used!"</string>
|
||||
<string name="msg_dc_insecure_symmetric_encryption_algo">"Insecure encryption algorithm has been used! This can happen because the application is out of date, or from an attack."</string>
|
||||
<string name="msg_dc_insecure_hash_algo">"Insecure hash algorithm has been used! This can happen because the application is out of date, or from an attack."</string>
|
||||
<string name="msg_dc_insecure_mdc_missing">"Missing the Modification Detection Code (MDC) packet! This can happen because the encrypting application is out of date, or from a downgrade attack."</string>
|
||||
<string name="msg_dc_insecure_key">"Insecure key: Either the bit length of RSA/DSA/ElGamal is too short or the ECC curve/algorithm is considered insecure! This can happen because the application is out of date, or from an attack."</string>
|
||||
|
||||
<!-- Messages for VerifySignedLiteralData operation -->
|
||||
<string name="msg_vl">"Starting signature check"</string>
|
||||
|
||||
Reference in New Issue
Block a user