it-swarm-korea.com

클라우드에서 암호화 비밀 (사용자 이름, 비밀번호) 공유를 안전하게 구현

이 정보를 수신하는 에이전트 (백그라운드 서비스)의 구성 파일을 푸시 (또는 다운로드 가능)해야하는 멀티 테넌트 (클라우드) 환경을 구축하고 있습니다. 구성의 정보 중 하나는 사용자 이름과 암호입니다.

에이전트가 클라우드에서 안전하게 식별 될 수 있다고 가정 할 때이 민감한 정보를 암호화, 공유, 푸시하는 데 어떤 암호화 및 보안 시스템을 사용 하시겠습니까?

공개 개인 키 쌍으로 충분합니까? 비밀은 각 에이전트의 공개 키로 암호화되고 암호화되지 않은 값은 폐기 될 것이라고 생각합니다.

이 구현에 대해 어떻게 생각하십니까? 이 응용 프로그램, Windows Azure, ASP.NET MVC 및 Silverlight에서 주로 C #을 사용합니다.

샘플 에이전트 측 코드 (RSACryptoProvider)

그러면 C #으로 공개 개인 키 쌍이 생성되고 키가 디스크에 저장되지 않습니다.

public static void AssignNewKey(){
    const int PROVIDER_RSA_FULL = 1;
    const string CONTAINER_NAME = "KeyContainer";
    CspParameters cspParams;
    cspParams = new CspParameters(PROVIDER_RSA_FULL);
    cspParams.KeyContainerName = CONTAINER_NAME;
// CspProviderFlags.UseNonExportableKey -- Prevent less-knowledgeable attacks against PK
// CspProviderFlags.UseUserProtectedKey -- Interactively Prompt for password
    cspParams.Flags = CspProviderFlags.UseMachineKeyStore;
    cspParams.ProviderName = "Microsoft Strong Cryptographic Provider";
    rsa = new RSACryptoServiceProvider(cspParams);

    rsa.PersistKeyInCsp = false;

    string publicPrivateKeyXML = rsa.ToXmlString(true);
    string publicOnlyKeyXML = rsa.ToXmlString(false);
    // do stuff with keys...
}

샘플 에이전트 측 코드 옵션 2 (Bouncy Castle)

public void GenerateKey(string username, string password, string keyStoreUrl)
        {
            IAsymmetricCipherKeyPairGenerator kpg = new RsaKeyPairGenerator();
            kpg.Init(new RsaKeyGenerationParameters(BigInteger.ValueOf(0x13), new SecureRandom(), 1024, 8));
            AsymmetricCipherKeyPair kp = kpg.GenerateKeyPair();

            FileStream out1 = new FileInfo(string.Format("{0}secret.asc", keyStoreUrl)).OpenWrite();
            FileStream out2 = new FileInfo(string.Format("{0}pub.asc", keyStoreUrl)).OpenWrite();

            ExportKeyPair(out1, out2, kp.Public, kp.Private, username, password.ToCharArray(), true);

            out1.Close();
            out2.Close();

        }

private static void ExportKeyPair(
            Stream secretOut,
            Stream publicOut,
            AsymmetricKeyParameter publicKey,
            AsymmetricKeyParameter privateKey,
            string identity,
            char[] passPhrase,
            bool armor)
        {
            if (armor)
            {
                secretOut = new ArmoredOutputStream(secretOut);
            }

            PgpSecretKey secretKey = new PgpSecretKey(
                PgpSignature.DefaultCertification,
                PublicKeyAlgorithmTag.RsaGeneral,
                publicKey,
                privateKey,
                DateTime.Now,
                identity,
                SymmetricKeyAlgorithmTag.Cast5,
                passPhrase,
                null,
                null,
                new SecureRandom()
                //                ,"BC"
                );

            secretKey.Encode(secretOut);

            secretOut.Close();

            if (armor)
            {
                publicOut = new ArmoredOutputStream(publicOut);
            }

            PgpPublicKey key = secretKey.PublicKey;

            key.Encode(publicOut);

            publicOut.Close();
        }
7
goodguys_activate

각 에이전트의 공개 키를 사용하여 데이터를 암호화하는 것은 에이전트를 암시 적으로 인증하는 방법입니다. 에이전트가 실제로 데이터를 수신했는지 (통신이 잠재적으로 악의적 인 클라우드를 통과하는 설정에서) 실제로는 알 수 없지만 적절한 에이전트 만 데이터를 해독 할 수 있다는 것을 알고 있습니다. 따라서 데이터가 어딘가로 간다면 올바른 에이전트로 이동합니다. 이것은 문제에 대한 좋은 도구처럼 보입니다.

공개 키 암호화는 과도 할 수 있습니다. 수신 에이전트와 데이터 발신자가 공통 비밀 키 (수십 개의 임의 바이트 묶음)를 공유하도록 할 수있는 경우 대칭 암호화를 사용하여 데이터를 암호화 할 수 있습니다.

몇 가지 문제가 있습니다.

  • 공개 키 암호화 체계를 사용하는 경우 발신자는 사전에 신뢰할 수있는 방식으로 에이전트의 공개 키를 알아야합니다. 에이전트를 만들고 배포하는 방법에 따라 이것은 쉽지 않을 수도 있습니다.

  • 에이전트가 데이터를 수신하는 힘은 개인 키 (또는 대칭 암호화의 경우 공통 공유 비밀 키)에 대한 지식에서 비롯됩니다. 키 사본을 획득하면 공격자가 암호화 된 데이터를 해독 할 수 있으므로 해당 개인 키의 저장을 관리해야합니다.

  • 비대칭 암호화는 제한된 메시지에 대해서만 작동합니다. 예를 들어, 1024 비트 RSA 및 일반적인 PKCS # 1 패딩을 사용하면 메시지에 117 바이트로 하드 제한이 있습니다. 또한 RSA 암호화 및 복호화는 너무 빠르지 않습니다 (대부분의 경우에는 충분히 빠르지 만). 따라서 메시지 자체를 암호화하지 않고 대칭 암호화 시스템 (AES)을 사용하여 데이터 자체를 암호화하는 데 사용하는 임의의 비밀 키 (무작위 바이트)를 사용하는 하이브리드 방식을 사용하는 것이 일반적입니다. ), 이는 빠르고 무제한 메시지 길이입니다.

  • 악의적 인 수동 공격자가있는 경우 종종 능동적 인 공격자도 있습니다. 수동적 공격자는 데이터를 감시 할뿐입니다. 적극적인 공격자가 수정할 수도 있습니다. 암호화 된 데이터를 미묘하게 수정하고 결과를 관찰하여 만들 수있는 많은 스마트 공격이 있습니다 (SSL 연결로 전송 된 암호는 그런 방식으로 복구 됨). 따라서 암호화 만 필요하지 않고 무결성 검사도 필요합니다. 한 가지 가능성은 발신자가 암호화 된 패킷에 서명하고 에이전트가이를 해독하기 전에 서명을 확인하는 것입니다.

무수히 많은 배포 된 시스템이 이러한 문제를 겪었으며 사전에 효율적으로 테스트 할 수 없습니다. 당신은 정말로 이 모든 것을 위해 기존 표준 형식을 사용해야하며 이미 제대로 구현하려는 노력을 거친 지원 라이브러리와 함께 사용해야합니다. CMS 또는 OpenPGP 를 사용하는 것이 좋습니다. C #이 이미 지원하는지 여부는 모르겠지만 (특히 OpenPGP의 경우에는 의심 스럽습니다) Bouncy Castle 지원하는 오픈 소스 라이브러리입니다 (C # 버전이 있음).

마지막으로 동일한 데이터를 수신해야하는 에이전트가 많은 경우 보안 비밀로 데이터를 암호화 한 번 하는 것이 네트워크 효율성이 더 높을 수 있습니다. 그런 다음 각 에이전트의 공개 키로 암호화합니다. 이것을 방송 암호화 라고하며 유료 TV 공급 업체가하는 일입니다 (그들은 수백만 명의 고객에게 매우 동일한 방대한 콘텐츠를 전송하므로 방송이 가치있을뿐만 아니라 완전히 필요합니다).

9
Thomas Pornin

공개 키/개인 키 쌍-클라우드의 데이터가 악의적 인 행위자가 액세스 할 수 있다고 가정해야하므로이 시나리오에 적합 해 보입니다. 클라우드 환경에 대한 취약한 보안에도 불구하고 에이전트를 위해 클라우드에 저장 한 데이터는 암호화되고 인증 될 수 있습니다.

Thomas Pornin의 대답은 내 대답보다 훨씬 더 나은 측면을 다룹니다. 그래서 추가 할 유일한 추가 비트는 구현을 테스트하는 데 필수적, 약한 구성 또는 잘못된 코드로 구현하면 보안 모델이 손상 될 수 있습니다.

2
Rory Alsop

귀하의 질문에서 이해했듯이 컴퓨터 네트워크 인증 프로토콜 ( "을 사용하여 비보안 네트워크를 통해 통신하는 노드가 안전한 방식으로 서로의 신원을 증명할 수 있도록해야합니다 ") 통신 프로토콜의 작업, 목적 및 사양은 다음을 유지하는 것입니다.

  • 선도:
  • 순방향 비밀
  • 알려진 키 복원력
  • 키 인증
  • 키 확인
  • 명시 적 키 인증

위의 사양을 달성하기 위해 고유 한 통신 프로토콜을 설계 할 수 있습니다. 가장 간단한 방법은 다음을 사용하는 것입니다.

S는 신뢰할 수있는 제 3 자이고 A와 B는 안전한 통신을 원하는 클라이언트입니다.

  • A → S : IDA ║IDB
  • S → A : 캅
  • A → B : Kab║IDA

다음과 같이 프로토콜을 개선 할 수 있습니다.

  • A → S : IDA ║IDB
  • S → A : E (Kas, [Kab]) ║ E (Kbs, [Kab])
  • A → B : E (Kbs, [Kab]) ║IDA

그러나 위의 두 프로토콜에는 많은 문제가 있습니다. 프로토콜이 충분히 강력한 지 확인하려면 나열된 프로토콜 중 하나를 사용하는 것이 좋습니다.

0
Am1rr3zA