mirror of
https://github.com/hierynomus/sshj.git
synced 2025-12-06 07:10:53 +03:00
Added PKCS5 key file support (#262)
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -12,6 +12,9 @@
|
||||
# Output dirs
|
||||
target/
|
||||
build/
|
||||
docs/
|
||||
.gradle/
|
||||
sshj.jar
|
||||
|
||||
|
||||
# MacOS X
|
||||
.DS_Store
|
||||
|
||||
@@ -107,7 +107,7 @@ public class StreamCopier {
|
||||
log.debug("Done copying from {}", in);
|
||||
doneEvent.set();
|
||||
} catch (IOException ioe) {
|
||||
log.error("In pipe from {} to {}: {}", in, out, ioe);
|
||||
log.error(String.format("In pipe from %1$s to %2$s", in.toString(), out.toString()), ioe);
|
||||
doneEvent.deliverError(ioe);
|
||||
}
|
||||
}
|
||||
@@ -136,7 +136,7 @@ public class StreamCopier {
|
||||
|
||||
final double timeSeconds = (System.currentTimeMillis() - startTime) / 1000.0;
|
||||
final double sizeKiB = count / 1024.0;
|
||||
log.debug("{} KiB transferred in {} seconds ({} KiB/s)", sizeKiB, timeSeconds, (sizeKiB / timeSeconds));
|
||||
log.debug(String.format("%1$,.1f KiB transferred in %2$,.1f seconds (%3$,.2f KiB/s)", sizeKiB, timeSeconds, (sizeKiB / timeSeconds)));
|
||||
|
||||
if (length != -1 && read == -1)
|
||||
throw new IOException("Encountered EOF, could not transfer " + length + " bytes");
|
||||
|
||||
@@ -262,6 +262,13 @@ public class OpenSSHKnownHosts
|
||||
}
|
||||
|
||||
public interface HostEntry {
|
||||
KeyType getType();
|
||||
|
||||
String getFingerprint();
|
||||
|
||||
boolean appliesTo(String host)
|
||||
throws IOException;
|
||||
|
||||
boolean appliesTo(KeyType type, String host)
|
||||
throws IOException;
|
||||
|
||||
@@ -279,6 +286,22 @@ public class OpenSSHKnownHosts
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyType getType() {
|
||||
return KeyType.UNKNOWN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFingerprint() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean appliesTo(String host)
|
||||
throws IOException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean appliesTo(KeyType type, String host) {
|
||||
return false;
|
||||
@@ -308,6 +331,16 @@ public class OpenSSHKnownHosts
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFingerprint() {
|
||||
return SecurityUtils.getFingerprint(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verify(PublicKey key)
|
||||
throws IOException {
|
||||
@@ -349,6 +382,12 @@ public class OpenSSHKnownHosts
|
||||
return hostnames;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean appliesTo(String host)
|
||||
throws IOException {
|
||||
return hosts.contains(host);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean appliesTo(KeyType type, String host)
|
||||
throws IOException {
|
||||
@@ -377,6 +416,12 @@ public class OpenSSHKnownHosts
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean appliesTo(String host)
|
||||
throws IOException {
|
||||
return hashedHost.equals(hashHost(host));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean appliesTo(KeyType type, String host)
|
||||
throws IOException {
|
||||
@@ -426,4 +471,4 @@ public class OpenSSHKnownHosts
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package net.schmizz.sshj.userauth.keyprovider;
|
||||
* @version $Id:$
|
||||
*/
|
||||
public enum KeyFormat {
|
||||
PKCS5,
|
||||
PKCS8,
|
||||
OpenSSH,
|
||||
PuTTY,
|
||||
|
||||
@@ -96,9 +96,10 @@ public class KeyProviderUtil {
|
||||
if (separatePubKey) {
|
||||
// Can delay asking for password since have unencrypted pubkey
|
||||
return KeyFormat.OpenSSH;
|
||||
} else {
|
||||
// More general
|
||||
} else if (header.indexOf("BEGIN PRIVATE KEY") != -1 || header.indexOf("BEGIN ENCRYPTED PRIVATE KEY") != -1) {
|
||||
return KeyFormat.PKCS8;
|
||||
} else {
|
||||
return KeyFormat.PKCS5;
|
||||
}
|
||||
} else if (header.startsWith("PuTTY-User-Key-File-")) {
|
||||
return KeyFormat.PuTTY;
|
||||
|
||||
@@ -0,0 +1,309 @@
|
||||
/*
|
||||
* Copyright (C)2009 - SSHJ Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.schmizz.sshj.userauth.keyprovider;
|
||||
|
||||
import net.schmizz.sshj.common.Base64;
|
||||
import net.schmizz.sshj.common.IOUtils;
|
||||
import net.schmizz.sshj.common.KeyType;
|
||||
import net.schmizz.sshj.transport.cipher.AES128CBC;
|
||||
import net.schmizz.sshj.transport.cipher.AES192CBC;
|
||||
import net.schmizz.sshj.transport.cipher.AES256CBC;
|
||||
import net.schmizz.sshj.transport.cipher.Cipher;
|
||||
import net.schmizz.sshj.transport.cipher.NoneCipher;
|
||||
import net.schmizz.sshj.transport.cipher.TripleDESCBC;
|
||||
import net.schmizz.sshj.transport.digest.Digest;
|
||||
import net.schmizz.sshj.transport.digest.MD5;
|
||||
import net.schmizz.sshj.userauth.password.PasswordFinder;
|
||||
import net.schmizz.sshj.userauth.password.PasswordUtils;
|
||||
import net.schmizz.sshj.userauth.password.PrivateKeyFileResource;
|
||||
import net.schmizz.sshj.userauth.password.PrivateKeyReaderResource;
|
||||
import net.schmizz.sshj.userauth.password.PrivateKeyStringResource;
|
||||
import net.schmizz.sshj.userauth.password.Resource;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.KeyPair;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.spec.DSAPrivateKeySpec;
|
||||
import java.security.spec.DSAPublicKeySpec;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.RSAPrivateKeySpec;
|
||||
import java.security.spec.RSAPublicKeySpec;
|
||||
import java.util.Arrays;
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
|
||||
/** Represents a PKCS5-encoded key file. This is the format typically used by OpenSSH, OpenSSL, Amazon, etc. */
|
||||
public class PKCS5KeyFile
|
||||
implements FileKeyProvider {
|
||||
|
||||
public static class Factory
|
||||
implements net.schmizz.sshj.common.Factory.Named<FileKeyProvider> {
|
||||
|
||||
@Override
|
||||
public FileKeyProvider create() {
|
||||
return new PKCS5KeyFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "PKCS5";
|
||||
}
|
||||
}
|
||||
|
||||
protected PasswordFinder pwdf;
|
||||
protected Resource<?> resource;
|
||||
protected KeyPair kp;
|
||||
|
||||
protected KeyType type;
|
||||
|
||||
protected char[] passphrase; // for blanking out
|
||||
|
||||
@Override
|
||||
public PrivateKey getPrivate()
|
||||
throws IOException {
|
||||
return kp != null ? kp.getPrivate() : (kp = readKeyPair()).getPrivate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PublicKey getPublic()
|
||||
throws IOException {
|
||||
return kp != null ? kp.getPublic() : (kp = readKeyPair()).getPublic();
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyType getType()
|
||||
throws IOException {
|
||||
return type != null ? type : (type = KeyType.fromKey(getPublic()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Reader location) {
|
||||
assert location != null;
|
||||
resource = new PrivateKeyReaderResource(location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Reader location, PasswordFinder pwdf) {
|
||||
init(location);
|
||||
this.pwdf = pwdf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(File location) {
|
||||
assert location != null;
|
||||
resource = new PrivateKeyFileResource(location.getAbsoluteFile());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(File location, PasswordFinder pwdf) {
|
||||
init(location);
|
||||
this.pwdf = pwdf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(String privateKey, String publicKey) {
|
||||
assert privateKey != null;
|
||||
assert publicKey == null;
|
||||
resource = new PrivateKeyStringResource(privateKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(String privateKey, String publicKey, PasswordFinder pwdf) {
|
||||
init(privateKey, publicKey);
|
||||
this.pwdf = pwdf;
|
||||
}
|
||||
|
||||
protected KeyPair readKeyPair()
|
||||
throws IOException {
|
||||
BufferedReader reader = new BufferedReader(resource.getReader());
|
||||
try {
|
||||
String type = null;
|
||||
String line = null;
|
||||
Cipher cipher = new NoneCipher();
|
||||
StringBuffer sb = new StringBuffer();
|
||||
byte[] iv = new byte[0]; // salt
|
||||
while ((line = reader.readLine()) != null) {
|
||||
if (line.startsWith("-----BEGIN ") && line.endsWith(" PRIVATE KEY-----")) {
|
||||
int end = line.length() - 17;
|
||||
if (end > 11) {
|
||||
type = line.substring(11, line.length() - 17);
|
||||
} else {
|
||||
type = "UNKNOWN";
|
||||
}
|
||||
} else if (line.startsWith("-----END")) {
|
||||
break;
|
||||
} else if (type != null) {
|
||||
if (line.startsWith("Proc-Type: ")) {
|
||||
if (!"4,ENCRYPTED".equals(line.substring(11))) {
|
||||
throw new IOException("Unrecognized Proc-Type: " + line.substring(11));
|
||||
}
|
||||
} else if (line.startsWith("DEK-Info: ")) {
|
||||
int ptr = line.indexOf(",");
|
||||
if (ptr == -1) {
|
||||
throw new IOException("Unrecognized DEK-Info: " + line.substring(10));
|
||||
} else {
|
||||
String algorithm = line.substring(10,ptr);
|
||||
if ("DES-EDE3-CBC".equals(algorithm)) {
|
||||
cipher = new TripleDESCBC();
|
||||
iv = DatatypeConverter.parseHexBinary(line.substring(ptr+1));
|
||||
} else if ("AES-128-CBC".equals(algorithm)) {
|
||||
cipher = new AES128CBC();
|
||||
iv = DatatypeConverter.parseHexBinary(line.substring(ptr+1));
|
||||
} else if ("AES-192-CBC".equals(algorithm)) {
|
||||
cipher = new AES192CBC();
|
||||
iv = Base64.decode(line.substring(ptr+1));
|
||||
} else if ("AES-256-CBC".equals(algorithm)) {
|
||||
cipher = new AES256CBC();
|
||||
iv = Base64.decode(line.substring(ptr+1));
|
||||
} else {
|
||||
throw new IOException("Not a supported algorithm: " + algorithm);
|
||||
}
|
||||
}
|
||||
} else if (line.length() > 0) {
|
||||
sb.append(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
byte[] data = Base64.decode(sb.toString());
|
||||
if (pwdf != null) {
|
||||
boolean decrypted = false;
|
||||
do {
|
||||
CharBuffer cb = CharBuffer.wrap(pwdf.reqPassword(resource));
|
||||
ByteBuffer bb = IOUtils.UTF8.encode(cb);
|
||||
byte[] passphrase = Arrays.copyOfRange(bb.array(), bb.position(), bb.limit());
|
||||
Arrays.fill(cb.array(), '\u0000');
|
||||
Arrays.fill(bb.array(), (byte)0);
|
||||
byte[] key = new byte[cipher.getBlockSize()];
|
||||
iv = Arrays.copyOfRange(iv, 0, cipher.getIVSize());
|
||||
Digest md5 = new MD5();
|
||||
md5.init();
|
||||
int hsize = md5.getBlockSize();
|
||||
byte[] hn = new byte[key.length / hsize * hsize + (key.length % hsize == 0 ? 0 : hsize)];
|
||||
byte[] tmp = null;
|
||||
for (int i=0; i + hsize <= hn.length;) {
|
||||
if (tmp != null) {
|
||||
md5.update(tmp, 0, tmp.length);
|
||||
}
|
||||
md5.update(passphrase, 0, passphrase.length);
|
||||
md5.update(iv, 0, iv.length > 8 ? 8 : iv.length);
|
||||
tmp = md5.digest();
|
||||
System.arraycopy(tmp, 0, hn, i, tmp.length);
|
||||
i += tmp.length;
|
||||
}
|
||||
Arrays.fill(passphrase, (byte)0);
|
||||
System.arraycopy(hn, 0, key, 0, key.length);
|
||||
cipher.init(Cipher.Mode.Decrypt, key, iv);
|
||||
Arrays.fill(key, (byte)0);
|
||||
cipher.update(data, 0, data.length);
|
||||
decrypted = 0x30 == data[0];
|
||||
} while (!decrypted && pwdf.shouldRetry(resource));
|
||||
}
|
||||
if (0x30 != data[0]) {
|
||||
throw new IOException("Failed to decrypt key");
|
||||
}
|
||||
|
||||
ASN1Data asn = new ASN1Data(data);
|
||||
if ("RSA".equals(type)) {
|
||||
KeyFactory factory = KeyFactory.getInstance("RSA");
|
||||
asn.readNext();
|
||||
BigInteger modulus = asn.readNext();
|
||||
BigInteger pubExp = asn.readNext();
|
||||
BigInteger prvExp = asn.readNext();
|
||||
PublicKey pubKey = factory.generatePublic(new RSAPublicKeySpec(modulus, pubExp));
|
||||
PrivateKey prvKey = factory.generatePrivate(new RSAPrivateKeySpec(modulus, prvExp));
|
||||
return new KeyPair(pubKey, prvKey);
|
||||
} else if ("DSA".equals(type)) {
|
||||
KeyFactory factory = KeyFactory.getInstance("DSA");
|
||||
asn.readNext();
|
||||
BigInteger p = asn.readNext();
|
||||
BigInteger q = asn.readNext();
|
||||
BigInteger g = asn.readNext();
|
||||
BigInteger pub = asn.readNext();
|
||||
BigInteger prv = asn.readNext();
|
||||
PublicKey pubKey = factory.generatePublic(new DSAPublicKeySpec(pub, p, q, g));
|
||||
PrivateKey prvKey = factory.generatePrivate(new DSAPrivateKeySpec(prv, p, q, g));
|
||||
return new KeyPair(pubKey, prvKey);
|
||||
} else {
|
||||
throw new IOException("Unrecognized key type: " + type);
|
||||
}
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new IOException(e);
|
||||
} catch (InvalidKeySpecException e) {
|
||||
throw new IOException(e);
|
||||
} finally {
|
||||
reader.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PKCS5KeyFile{resource=" + resource + "}";
|
||||
}
|
||||
|
||||
class ASN1Data {
|
||||
private byte[] buff;
|
||||
private int index, length;
|
||||
|
||||
ASN1Data(byte[] buff) throws IOException {
|
||||
this.buff = buff;
|
||||
index = 0;
|
||||
if (buff[index++] != (byte)0x30) {
|
||||
throw new IOException("Not ASN.1 data");
|
||||
}
|
||||
length = buff[index++] & 0xff;
|
||||
if ((length & 0x80) != 0) {
|
||||
int counter = length & 0x7f;
|
||||
length = 0;
|
||||
while (counter-- > 0) {
|
||||
length = (length << 8) + (buff[index++] & 0xff);
|
||||
}
|
||||
}
|
||||
if ((index + length) > buff.length) {
|
||||
throw new IOException("Length mismatch: " + buff.length + " != " + (index + length));
|
||||
}
|
||||
}
|
||||
|
||||
BigInteger readNext() throws IOException {
|
||||
if (index >= length) {
|
||||
throw new EOFException();
|
||||
} else if (buff[index++] != 0x02) {
|
||||
throw new IOException("Not an int code: " + Integer.toHexString(0xff & buff[index]));
|
||||
}
|
||||
int length = buff[index++] & 0xff;
|
||||
if ((length & 0x80) != 0) {
|
||||
int counter = length & 0x7f;
|
||||
length = 0;
|
||||
while (counter-- > 0) {
|
||||
length = (length << 8) + (buff[index++] & 0xff);
|
||||
}
|
||||
}
|
||||
byte[] sequence = new byte[length];
|
||||
System.arraycopy(buff, index, sequence, 0, length);
|
||||
index += length;
|
||||
return new BigInteger(sequence);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,12 @@ public class KeyProviderUtilTest {
|
||||
assertEquals(KeyFormat.OpenSSH, format);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPkcs5() throws IOException {
|
||||
KeyFormat format = KeyProviderUtil.detectKeyFileFormat(new File(ROOT, "pkcs5"));
|
||||
assertEquals(KeyFormat.PKCS5, format);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPkcs8() throws IOException {
|
||||
KeyFormat format = KeyProviderUtil.detectKeyFileFormat(new File(ROOT, "pkcs8"));
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C)2009 - SSHJ Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.schmizz.sshj.keyprovider;
|
||||
|
||||
import net.schmizz.sshj.common.KeyType;
|
||||
import net.schmizz.sshj.userauth.keyprovider.FileKeyProvider;
|
||||
import net.schmizz.sshj.userauth.keyprovider.PKCS5KeyFile;
|
||||
import net.schmizz.sshj.util.KeyUtil;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.GeneralSecurityException;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class PKCS5KeyFileTest {
|
||||
|
||||
static final FileKeyProvider rsa = new PKCS5KeyFile();
|
||||
|
||||
static final String modulus = "a19f65e93926d9a2f5b52072db2c38c54e6cf0113d31fa92ff827b0f3bec609c45ea84264c88e64adba11ff093ed48ee0ed297757654b0884ab5a7e28b3c463bc9074b32837a2b69b61d914abf1d74ccd92b20fa44db3b31fb208c0dd44edaeb4ab097118e8ee374b6727b89ad6ce43f1b70c5a437ccebc36d2dad8ae973caad15cd89ae840fdae02cae42d241baef8fda8aa6bbaa54fd507a23338da6f06f61b34fb07d560e63fbce4a39c073e28573c2962cedb292b14b80d1b4e67b0465f2be0e38526232d0a7f88ce91a055fde082038a87ed91f3ef5ff971e30ea6cccf70d38498b186621c08f8fdceb8632992b480bf57fc218e91f2ca5936770fe9469";
|
||||
static final String pubExp = "23";
|
||||
static final String privExp = "57bcee2e2656eb2c94033d802dd62d726c6705fabad1fd0df86b67600a96431301620d395cbf5871c7af3d3974dfe5c30f5c60d95d7e6e75df69ed6c5a36a9c8aef554b5058b76a719b8478efa08ad1ebf08c8c25fe4b9bc0bfbb9be5d4f60e6213b4ab1c26ad33f5bba7d93e1cd65f65f5a79eb6ebfb32f930a2b0244378b4727acf83b5fb376c38d4abecc5dc3fc399e618e792d4c745d2dbbb9735242e5033129f2985ca3e28fa33cad2afe3e70e1b07ed2b6ec8a3f843fb4bffe3385ad211c6600618488f4ac70397e8eb036b82d811283dc728504cddbe1533c4dd31b1ec99ffa74fd0e3883a9cb3e2315cc1a56f55d38ed40520dd9ec91b4d2dd790d1b";
|
||||
|
||||
@Before
|
||||
public void setUp()
|
||||
throws UnsupportedEncodingException, GeneralSecurityException {
|
||||
rsa.init(new File("src/test/resources/id_rsa"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeys()
|
||||
throws IOException, GeneralSecurityException {
|
||||
assertEquals(KeyUtil.newRSAPublicKey(modulus, pubExp), rsa.getPublic());
|
||||
assertEquals(KeyUtil.newRSAPrivateKey(modulus, privExp), rsa.getPrivate());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testType()
|
||||
throws IOException {
|
||||
assertEquals(rsa.getType(), KeyType.RSA);
|
||||
}
|
||||
|
||||
}
|
||||
15
src/test/resources/keyformats/pkcs5
Normal file
15
src/test/resources/keyformats/pkcs5
Normal file
@@ -0,0 +1,15 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXQIBAAKBgQCm2IJ9gWDkPTlQ37NNUB0za5mCsQ8bi++8fyEqw7wl8ZNBh3qt
|
||||
TcnL+m+NZfQjUC0BXic7PcMLVm4A3ID2IAZQM+axfq9aL4huWerm4ua6tvdt4gQK
|
||||
oL1+8JFmdFvFw5pWW/NZHtkIprbVf7KtYrU27WmMhXruN071UzqLsw08cwIDAQAB
|
||||
AoGAHQ7cOyuLSnT3RISRX8eyLkBxLffUX8HRcQzbI+2PGTSnpuQHk6NWn/Xv87pr
|
||||
+LKABBr3zjOFgrX81p2QwEz3jDxNXzbOeZzhuvGXCX5GocuEO4n5EhDvXRDF4uht
|
||||
uvVV5FsQv/sTOR0PNo1nELiAA8k3NYDxraB83q7wtsmErtECQQDYWMnq8mwRe49d
|
||||
jIXNKJeNiuLUYxO3CLI/vx279gDKlKrt677trr1e7JZqm/DapEWG511tw3cW63gQ
|
||||
+qxtgkw1AkEAxW0UeaNaJd7DApqwGAcS1JkygCKwzQ4ns/Co15qUgMkqCkmQU9AU
|
||||
/zQpt2+BjdYVe50r/nr8K1KYwrBsyndrBwJBALe90N+FvFqswfoFmq2/R9eimTsg
|
||||
WmIdNKYHPs2gBNQIp5MhoSpkOdkgvi8U+d33nkUQwryyQbZpjbN98mufOfECQEML
|
||||
eBiW0NZrf+4yefqu7EYmgG/jWAdK91C0OaJ+bFAQAKbdtJXB5F+GZ2RUCbsRKNqB
|
||||
1Z7mRRyxQA9dupRHWaECQQCM9bbCtfGesgvZlhBavlWavu8iCvJlAbGdf5QMlFQE
|
||||
kABmZg84Fy3NUFCD+RXCuatb4Oo9P/WPIbjYiC4p0hLJ
|
||||
-----END RSA PRIVATE KEY-----
|
||||
@@ -1,15 +1,16 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXQIBAAKBgQCm2IJ9gWDkPTlQ37NNUB0za5mCsQ8bi++8fyEqw7wl8ZNBh3qt
|
||||
TcnL+m+NZfQjUC0BXic7PcMLVm4A3ID2IAZQM+axfq9aL4huWerm4ua6tvdt4gQK
|
||||
oL1+8JFmdFvFw5pWW/NZHtkIprbVf7KtYrU27WmMhXruN071UzqLsw08cwIDAQAB
|
||||
AoGAHQ7cOyuLSnT3RISRX8eyLkBxLffUX8HRcQzbI+2PGTSnpuQHk6NWn/Xv87pr
|
||||
+LKABBr3zjOFgrX81p2QwEz3jDxNXzbOeZzhuvGXCX5GocuEO4n5EhDvXRDF4uht
|
||||
uvVV5FsQv/sTOR0PNo1nELiAA8k3NYDxraB83q7wtsmErtECQQDYWMnq8mwRe49d
|
||||
jIXNKJeNiuLUYxO3CLI/vx279gDKlKrt677trr1e7JZqm/DapEWG511tw3cW63gQ
|
||||
+qxtgkw1AkEAxW0UeaNaJd7DApqwGAcS1JkygCKwzQ4ns/Co15qUgMkqCkmQU9AU
|
||||
/zQpt2+BjdYVe50r/nr8K1KYwrBsyndrBwJBALe90N+FvFqswfoFmq2/R9eimTsg
|
||||
WmIdNKYHPs2gBNQIp5MhoSpkOdkgvi8U+d33nkUQwryyQbZpjbN98mufOfECQEML
|
||||
eBiW0NZrf+4yefqu7EYmgG/jWAdK91C0OaJ+bFAQAKbdtJXB5F+GZ2RUCbsRKNqB
|
||||
1Z7mRRyxQA9dupRHWaECQQCM9bbCtfGesgvZlhBavlWavu8iCvJlAbGdf5QMlFQE
|
||||
kABmZg84Fy3NUFCD+RXCuatb4Oo9P/WPIbjYiC4p0hLJ
|
||||
-----END RSA PRIVATE KEY-----
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKbYgn2BYOQ9OVDf
|
||||
s01QHTNrmYKxDxuL77x/ISrDvCXxk0GHeq1Nycv6b41l9CNQLQFeJzs9wwtWbgDc
|
||||
gPYgBlAz5rF+r1oviG5Z6ubi5rq2923iBAqgvX7wkWZ0W8XDmlZb81ke2QimttV/
|
||||
sq1itTbtaYyFeu43TvVTOouzDTxzAgMBAAECgYAdDtw7K4tKdPdEhJFfx7IuQHEt
|
||||
99RfwdFxDNsj7Y8ZNKem5AeTo1af9e/zumv4soAEGvfOM4WCtfzWnZDATPeMPE1f
|
||||
Ns55nOG68ZcJfkahy4Q7ifkSEO9dEMXi6G269VXkWxC/+xM5HQ82jWcQuIADyTc1
|
||||
gPGtoHzervC2yYSu0QJBANhYyerybBF7j12Mhc0ol42K4tRjE7cIsj+/Hbv2AMqU
|
||||
qu3rvu2uvV7slmqb8NqkRYbnXW3DdxbreBD6rG2CTDUCQQDFbRR5o1ol3sMCmrAY
|
||||
BxLUmTKAIrDNDiez8KjXmpSAySoKSZBT0BT/NCm3b4GN1hV7nSv+evwrUpjCsGzK
|
||||
d2sHAkEAt73Q34W8WqzB+gWarb9H16KZOyBaYh00pgc+zaAE1AinkyGhKmQ52SC+
|
||||
LxT53feeRRDCvLJBtmmNs33ya5858QJAQwt4GJbQ1mt/7jJ5+q7sRiaAb+NYB0r3
|
||||
ULQ5on5sUBAApt20lcHkX4ZnZFQJuxEo2oHVnuZFHLFAD126lEdZoQJBAIz1tsK1
|
||||
8Z6yC9mWEFq+VZq+7yIK8mUBsZ1/lAyUVASQAGZmDzgXLc1QUIP5FcK5q1vg6j0/
|
||||
9Y8huNiILinSEsk=
|
||||
-----END PRIVATE KEY-----
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
|
||||
|
||||
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXQIBAAKBgQCm2IJ9gWDkPTlQ37NNUB0za5mCsQ8bi++8fyEqw7wl8ZNBh3qt
|
||||
TcnL+m+NZfQjUC0BXic7PcMLVm4A3ID2IAZQM+axfq9aL4huWerm4ua6tvdt4gQK
|
||||
oL1+8JFmdFvFw5pWW/NZHtkIprbVf7KtYrU27WmMhXruN071UzqLsw08cwIDAQAB
|
||||
AoGAHQ7cOyuLSnT3RISRX8eyLkBxLffUX8HRcQzbI+2PGTSnpuQHk6NWn/Xv87pr
|
||||
+LKABBr3zjOFgrX81p2QwEz3jDxNXzbOeZzhuvGXCX5GocuEO4n5EhDvXRDF4uht
|
||||
uvVV5FsQv/sTOR0PNo1nELiAA8k3NYDxraB83q7wtsmErtECQQDYWMnq8mwRe49d
|
||||
jIXNKJeNiuLUYxO3CLI/vx279gDKlKrt677trr1e7JZqm/DapEWG511tw3cW63gQ
|
||||
+qxtgkw1AkEAxW0UeaNaJd7DApqwGAcS1JkygCKwzQ4ns/Co15qUgMkqCkmQU9AU
|
||||
/zQpt2+BjdYVe50r/nr8K1KYwrBsyndrBwJBALe90N+FvFqswfoFmq2/R9eimTsg
|
||||
WmIdNKYHPs2gBNQIp5MhoSpkOdkgvi8U+d33nkUQwryyQbZpjbN98mufOfECQEML
|
||||
eBiW0NZrf+4yefqu7EYmgG/jWAdK91C0OaJ+bFAQAKbdtJXB5F+GZ2RUCbsRKNqB
|
||||
1Z7mRRyxQA9dupRHWaECQQCM9bbCtfGesgvZlhBavlWavu8iCvJlAbGdf5QMlFQE
|
||||
kABmZg84Fy3NUFCD+RXCuatb4Oo9P/WPIbjYiC4p0hLJ
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKbYgn2BYOQ9OVDf
|
||||
s01QHTNrmYKxDxuL77x/ISrDvCXxk0GHeq1Nycv6b41l9CNQLQFeJzs9wwtWbgDc
|
||||
gPYgBlAz5rF+r1oviG5Z6ubi5rq2923iBAqgvX7wkWZ0W8XDmlZb81ke2QimttV/
|
||||
sq1itTbtaYyFeu43TvVTOouzDTxzAgMBAAECgYAdDtw7K4tKdPdEhJFfx7IuQHEt
|
||||
99RfwdFxDNsj7Y8ZNKem5AeTo1af9e/zumv4soAEGvfOM4WCtfzWnZDATPeMPE1f
|
||||
Ns55nOG68ZcJfkahy4Q7ifkSEO9dEMXi6G269VXkWxC/+xM5HQ82jWcQuIADyTc1
|
||||
gPGtoHzervC2yYSu0QJBANhYyerybBF7j12Mhc0ol42K4tRjE7cIsj+/Hbv2AMqU
|
||||
qu3rvu2uvV7slmqb8NqkRYbnXW3DdxbreBD6rG2CTDUCQQDFbRR5o1ol3sMCmrAY
|
||||
BxLUmTKAIrDNDiez8KjXmpSAySoKSZBT0BT/NCm3b4GN1hV7nSv+evwrUpjCsGzK
|
||||
d2sHAkEAt73Q34W8WqzB+gWarb9H16KZOyBaYh00pgc+zaAE1AinkyGhKmQ52SC+
|
||||
LxT53feeRRDCvLJBtmmNs33ya5858QJAQwt4GJbQ1mt/7jJ5+q7sRiaAb+NYB0r3
|
||||
ULQ5on5sUBAApt20lcHkX4ZnZFQJuxEo2oHVnuZFHLFAD126lEdZoQJBAIz1tsK1
|
||||
8Z6yC9mWEFq+VZq+7yIK8mUBsZ1/lAyUVASQAGZmDzgXLc1QUIP5FcK5q1vg6j0/
|
||||
9Y8huNiILinSEsk=
|
||||
-----END PRIVATE KEY-----
|
||||
|
||||
Reference in New Issue
Block a user