Archivos por Etiqueta: security

Amazon: Protect Instance Metadata and User Data

Es una practica extendida almacenar las credenciales en el “user-data”, el problema es que desde una instancia de EC2 cualquier usuario de la maquina, autorizado o no, puede acceder a estos datos.

Ejemplo:

curl http://169.254.169.254/latest/user-data

Una regla de iptables para evitar estos accesos, salvo para el usuario “root” (uid=0):

iptables -A OUTPUT \
  -d 169.254.169.254/32 -p tcp --dport 80 \
  -m owner ! --uid-owner 0 \
  -j REJECT --reject-with tcp-reset

References:
EC2 – Instance Metadata and User Data
The best method for passing AWS credentials as user data to an EC2 instance?

Java: undocumented sun.security.x509

Generando certificados autofirmados X.509 usando las (tristemente) indocumentadas sun.security.x509; la alternativa es usar Bouncy Castle (que cambian las APIs de una version a otra)… :-(

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.Date;
import java.util.Vector;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;

import javax.xml.bind.DatatypeConverter;

import sun.security.util.ObjectIdentifier;
import sun.security.x509.AlgorithmId;
import sun.security.x509.AuthorityKeyIdentifierExtension;
import sun.security.x509.BasicConstraintsExtension;
import sun.security.x509.CertificateAlgorithmId;
import sun.security.x509.CertificateExtensions;
import sun.security.x509.CertificateIssuerName;
import sun.security.x509.CertificateSerialNumber;
import sun.security.x509.CertificateSubjectName;
import sun.security.x509.CertificateValidity;
import sun.security.x509.CertificateVersion;
import sun.security.x509.CertificateX509Key;
import sun.security.x509.ExtendedKeyUsageExtension;
import sun.security.x509.KeyIdentifier;
import sun.security.x509.SubjectKeyIdentifierExtension;
import sun.security.x509.X500Name;
import sun.security.x509.X509CertImpl;
import sun.security.x509.X509CertInfo;

public class TestX509 {

	/**
	 * Create a self-signed X.509 Certificate
	 * @param dn the X.509 Distinguished Name, eg "CN=Test"
	 * @param pair the KeyPair
	 * @param days how many days from now the Certificate is valid for
	 */ 
	static X509Certificate generateCertificate(String dn, KeyPair pair, int days) throws Exception {
		PrivateKey privkey = pair.getPrivate();
		X509CertInfo info = new X509CertInfo();
		Date from = new Date();
		Date to = new Date(from.getTime() + days * 86400000L);
		CertificateValidity interval = new CertificateValidity(from, to);
		int sn = (int)((System.currentTimeMillis()/1000) & 0xFFFFFFFF);
		X500Name owner = new X500Name(dn);

		AlgorithmId algo = new AlgorithmId(AlgorithmId.sha1WithRSAEncryption_oid);
		info.set(X509CertInfo.VALIDITY, interval);
		info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(sn));
		info.set(X509CertInfo.SUBJECT, new CertificateSubjectName(owner));
		info.set(X509CertInfo.ISSUER, new CertificateIssuerName(owner));
		info.set(X509CertInfo.KEY, new CertificateX509Key(pair.getPublic()));
		info.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3));
		info.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(algo));

		// Extensions
		CertificateExtensions ext = new CertificateExtensions();
		ext.set(BasicConstraintsExtension.NAME, new BasicConstraintsExtension(Boolean.TRUE, true, 0)); // Critical|isCA|pathLen
		ext.set(SubjectKeyIdentifierExtension.NAME, new SubjectKeyIdentifierExtension(new KeyIdentifier(pair.getPublic()).getIdentifier()));
		ext.set(AuthorityKeyIdentifierExtension.NAME, new AuthorityKeyIdentifierExtension(new KeyIdentifier(pair.getPublic()), null, null));
		// Extended Key Usage Extension
		Vector<ObjectIdentifier> ekue = new Vector<ObjectIdentifier>();
		ekue.add(new ObjectIdentifier(new int[] { 1, 3, 6, 1, 5, 5, 7, 3, 1 })); // Server
		ekue.add(new ObjectIdentifier(new int[] { 1, 3, 6, 1, 5, 5, 7, 3, 2 })); // Client
		ext.set(ExtendedKeyUsageExtension.NAME, new ExtendedKeyUsageExtension(Boolean.FALSE, ekue));
		info.set(X509CertInfo.EXTENSIONS, ext);

		// Sign the X.509
		X509CertImpl cert = new X509CertImpl(info);
		cert.sign(privkey, algo.getName());
		return cert;
	}

	static void writeCertificate(OutputStream out, X509Certificate crt) throws Exception {
		final int BLOCK_SIZE = 64;
		byte[] buf =  DatatypeConverter.printBase64Binary(crt.getEncoded()).getBytes();
		out.write("-----BEGIN CERTIFICATE-----\r\n".getBytes());
		for (int i = 0; i < buf.length; i += BLOCK_SIZE) {
			out.write(buf, i, Math.min(BLOCK_SIZE, buf.length - i));
			out.write('\r');
			out.write('\n');
		}
		out.write("-----END CERTIFICATE-----\r\n".getBytes());
		out.flush();
		out.close();
	}

	static void writeKey(OutputStream out,  PrivateKey pk) throws Exception {
		final int BLOCK_SIZE = 64;
		byte[] buf =  DatatypeConverter.printBase64Binary(pk.getEncoded()).getBytes();
		out.write("-----BEGIN RSA PRIVATE KEY-----\r\n".getBytes());
		for (int i = 0; i < buf.length; i += BLOCK_SIZE) {
			out.write(buf, i, Math.min(BLOCK_SIZE, buf.length - i));
			out.write('\r');
			out.write('\n');
		}
		out.write("-----END RSA PRIVATE KEY-----\r\n".getBytes());
		out.flush();
		out.close();
	}

	public static void main(String[] args) throws Exception {
		KeyPairGenerator kgAsym = KeyPairGenerator.getInstance("RSA");
		kgAsym.initialize(1024); // TODO: RSA { 1024, 1536, 2048 }
		KeyPair kp = kgAsym.genKeyPair();
		X509Certificate crt = generateCertificate("CN=Test1", kp, 365);
		System.out.println(crt);
		File keyFile = new File(System.getProperty("java.io.tmpdir"), "test.key");
		File crtFile = new File(System.getProperty("java.io.tmpdir"), "test.crt");
		writeKey(new FileOutputStream(keyFile), kp.getPrivate());
		writeCertificate(new FileOutputStream(crtFile), crt);
	}

}

Fuente Original: BFO*

Java: Password checks

Esta es la tipica funcion que deberia implementarse siempre para validaciones de passwords, buenos codigos de conducta que no siempre seguimos (usar mayusculas, minusculas, una cierta longitud, etc.)

Si quieres que tus passwords sean seguros… no lo dejes en manos del azar.

import java.util.Arrays;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
/**
 * Normas para los Passwords:
 * <ul> 
 * <li>Al menos 8 characters y no más de 28 caracteres</li>
 * <li>Al menos 1 caracter de cada grupo:</li>
 * <ul>
 * <li>Letras mayusculas <b>[A-Z]</b></li>
 * <li>Letras minusculas <b>[a-z]</b></li>
 * <li>Numeros <b>[0-9]</b></li>
 * <li>Caracteres especiales: <b><[{(#$%&*?!:.,=+-_~^)}]></b></li>
 * </ul>
 * <li>No espacios</li>
 * <li>No letras acentuadas</li>
 * <li>No partes del username o ID</li>
 * </ul>
 *
 */
public class PasswordChecker {
	static final char[] special_chars = "<[{(#$%&*?!:.,=+-_~^)}]>".toCharArray();
	//
	boolean dirty = true;
	//
	int countMay = 0; // Mayusculas
	int countMin = 0; // Minusculas
	int countNum = 0; // Numeros
	int countEsp = 0; // Especiales
	int countInv = 0; // Invalidos
	//
	final Pattern pnum = Pattern.compile("(\\d+)"); 	// numbers
	final Pattern plet = Pattern.compile("([a-z]+)"); 	// letters
	boolean invalidWords = true;
	//
	String user;
	String password;
	//

	// Static init
	{
		Arrays.sort(special_chars);
	}

	public PasswordChecker() {
		this("", "");
	}
	public PasswordChecker(String user, String password) {
		this.user = user;
		this.password = password;
		setDirty(true);
	}
	final void setDirty(final boolean dirty) {
		this.dirty = dirty;
	}

	public final PasswordChecker setUser(final String user) {
		this.user = user;
		setDirty(true);
		return this;
	}

	public final PasswordChecker setPassword(final String password) {
		this.password = password;
		setDirty(true);
		return this;
	}

	final void checkWords() {
		if (checkPattern(plet) || checkPattern(pnum)) {
			invalidWords = true;
		}
		else {
			invalidWords = false;
		}
	}

	final boolean checkPattern(final Pattern pat) {
		final String chkPassword = password.toLowerCase();
		final Matcher m = pat.matcher(user.toLowerCase());
		while (m.find()) {
			final String word = m.group();
			if (word.length() < 3) continue; // Skip short words
			if (chkPassword.contains(word)) {
				return true;
			}
		}
		return false;
	}

	final void countChars() {
		final int len = password.length();
		// Reset Counters
		countMay = countMin = countNum = countEsp = countInv = 0; 
		for (int i = 0; i < len; i++) {
			final char c = password.charAt(i);
			if ((c >= 'A') && (c <= 'Z')) {
				countMay++;
			}
			else if ((c >= 'a') && (c <= 'z')) {
				countMin++;
			}
			else if ((c >= '0') && (c <= '9')) {
				countNum++;
			}
			else if (Arrays.binarySearch(special_chars, c) >= 0) {
				countEsp++;
			}
			else {
				countInv++;
			}
		}
	}

	public boolean isValid() {
		if (dirty) {
			countChars();
			checkWords();
			setDirty(false);
		}
		return (
				(password.length() >= 8) && (password.length() <= 28) && 
				(countMay > 0) && (countMin > 0) && 
				(countNum > 0) && (countEsp > 0) &&
				(countInv == 0) && 
				(!invalidWords)
				);
	}

	public String toString() {
		final StringBuilder sb = new StringBuilder();
		if (dirty) {
			countChars();
			checkWords();
			setDirty(false);
		}
		sb
		.append("Length=").append(password.length()).append(" ")
		.append("Mayusculas=").append(countMay).append(" ")
		.append("Minusculas=").append(countMin).append(" ")
		.append("Numeros=").append(countNum).append(" ")
		.append("Especiales=").append(countEsp).append(" ")
		.append("Invalidos=").append(countInv).append(" ")
		.append("BlackWords=").append(invalidWords);
		return sb.toString();
	}

	static void testCheck(final String user, final String pass) {
		final StringBuilder sb = new StringBuilder(); 
		final PasswordChecker pwdchk = new PasswordChecker();
		pwdchk.setUser(user);
		pwdchk.setPassword(pass);
		sb
		.append("pwd=").append(pass).append(" ")
		.append("valid=").append(pwdchk.isValid()).append(" ")
		.append(pwdchk.toString());
		System.out.println(sb.toString());
	}

	public static void main(final String[] args) {
		testCheck("", "abCd9?"); // invalid
		testCheck("", "abcdefghik9?"); // invalid
		testCheck("", "abcdefghikABCDEFGHIJK-?*94231"); // invalid
		testCheck("", "azbZfg1?"); // valid
		testCheck("Usuario12", "UsuAriO?12"); // valid > invalid!
		testCheck("Z694812", "Zz!694812"); // valid > invalid!
		testCheck("SuperMan", "4r76*(SHhMi3"); // valid
	}
}

Lastest Full Source: PasswordChecker.java

AnonPaste & ZeroBin

AnonPaste is based on the open source ZeroBin software. It is a minimalist, opensource online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted in the browser using 256 bits AES. More information on the project page.

Fuentes:
AnonPaste
ZeroBin

A %d blogueros les gusta esto: