2

機密性の高い顧客識別情報を含む SAS のクライアント データを扱っています。課題は、数字/アルファベット/英数字のままになるようにフィールドをマスクすることです。SAS で Bitwise 関数 (BXOR、BOR、BAND) を使用する方法を見つけましたが、出力には、SAS が処理/ソート/マージできない特殊文字がいっぱいです。

キーに基づいてフィールド自体をスクランブルすることも考えましたが、それを見通すことができませんでした。課題は次のとおりです。

1) キーベースでなければならない 2) リバーシブルでなければならない。3) マスク/スクランブル フィールドは、SAS で使用できるように、数字/アルファベット/英数字のみにする必要があります。4) マスクされるフィールドには、アルファベットと数字の両方が含まれますが、長さがさまざまで、何百万もの観測値があります。

このマスキング/スクランブリングを実現する方法に関するヒントは、非常に高く評価されます:(

4

2 に答える 2

2

これは、単純なキーベースのソリューションです。ここでデータ ステップ ソリューションを紹介し、次に FCMP バージョンを少し紹介します。すべてを 48 から 127 の範囲 (数字、文字、@ > < などの一般的な文字) に保ちます。それは完全に英数字ではありませんが、この場合になぜそれが問題になるのか想像できません. この同じ方法を使用して、真の英数字のみにさらに減らすこともできますが、キーがさらに悪化し (値が 62 個しかない)、扱いにくくなります (3 つの連続しない範囲があるため)。

data construct_key;
length keystr $1500;
do _t = 1 to 1500;
  _rannum = ceil(ranuni(7)*80);
  *if _rannum=12 then _rannum=-15;
  substr(keystr,_t,1)=byte(47+_rannum);

end;
call symput('keystr',keystr);
run;
%put %bquote(&keystr);



data encrypted;
set sashelp.class;
retain key "&keystr";
length name_encrypt $30;
do _t = 1 to length(name);
  substr(name_encrypt,_t,1) = byte(mod(rank(substr(name,_t,1)) + rank(substr(key,1,1))-94,80)+47);
  key = substr(key,2);
end;
keep name:;
run;

data unencrypted;
set encrypted;
retain key "&keystr";
length name_unenc $30;
do _t = 1 to length(name_encrypt);
  substr(name_unenc,_t,1) = byte(
      mod(80+rank(substr(name_encrypt,_t,1)) - rank(substr(key,1,1)),80)
+47);
  key = substr(key,2);
end;
run;

このソリューションでは、中レベルの暗号化があります。80 個の可能な値を持つキーは、真に巧妙なハッカーを抑止するほど強力ではありませんが、ほとんどの目的には十分強力です。暗号化を解除するには、キー自体またはシードをキー アルゴリズムに渡す必要があります。これを複数回使用する場合は、毎回新しいシードを選択してください (データに関連するものではありません)。ゼロ (または非正の整数) をシードすると、毎回新しいキーが効果的に保証されますが、シードではなくキー自体を渡す必要があり、データ セキュリティの問題が発生する可能性があります (明らかに、キー自体は悪意のあるユーザーによって取得され、データとは別の場所に保存する必要があります)。シードを介してキーを渡す方がおそらく良いでしょう。

この種のアプローチを一般的に推奨するかどうかはわかりません。優れたアプローチは、優れた暗号化方法 (たとえば、PGP) を使用して SAS データセット全体を単純に暗号化することです。正確な解決策は異なる場合がありますが、たとえば、プロセスのほとんどのステップで実際には必要のない顧客情報がある場合は、その情報を残りの (機密でない) データから分離し、組み込むだけにする方がよい場合があります。それが必要なとき。

たとえば、ヘルスケア調査のためにクライアントのサンプルを抽出するプロセスがあります。数値の一意の識別子を除いて、顧客に関する情報を持たないデータセットから有効なレコードを選択します。サンプルを有効なレコードに絞り込んだら、別のデータセットから顧客情報を添付し、メール ファイルを作成します (暗号化されたディレクトリに保存されます)。これにより、可能な限りデータの機密性が保たれます。それは完璧ではありません - 一意の数値識別子は、たとえそれがプロジェクトの外で誰かが知っているものでなくても、依然として結びつきがあることを意味します - しかし、それは私たちの側で物事を可能な限り安全に保ちます.

FCMP バージョンは次のとおりです。

%let keylength=5;
%let seed=15;

proc fcmp outlib=work.funcs.test;
subroutine encrypt(value $,key $);
  length key $&keylength.;
  outargs value,key;
  do _t = 1 to lengthc(value);
    substr(value,_t,1) = byte(mod(rank(substr(value,_t,1)) + rank(substr(key,1,1))-62,96)+31);
    key = substr(key,2)||substr(key,1,1);
  end;
endsub;

subroutine unencrypt(value $,key $);
  length key $&keylength.;
  outargs value,key;
  do _t = 1 to lengthc(value);
    substr(value,_t,1) = byte(mod(96+rank(substr(value,_t,1)) - rank(substr(key,1,1)),96)+31);
    key = substr(key,2)||substr(key,1,1);
  end;
endsub;

subroutine gen_key(seed,keystr $);
  outargs keystr;
  length keystr $&keylength.;
  do _t = 1 to &keylength.;
    _rannum = ceil(ranuni(seed)*80);    
    substr(keystr,_t,1)=byte(47+_rannum);
  end;
endsub;
quit;

options cmplib=work.funcs;



data encrypted;
set sashelp.class;
length key $&keylength.;
retain key ' '; *the missing is to avoid the uninitialized variable warning;
if _n_ = 1 then call gen_key(&seed,key);
call encrypt(name,key);
drop key;
run;

data unencrypted;
set encrypted;
length key $&keylength.;
retain key ' ';
if _n_ = 1 then call gen_key(&seed,key);
call unencrypt(name,key);
run;

これはやや堅牢です。48 からではなく 32 から 127 までの文字を許可します。つまり、スペースを適切に処理します。(タブはまだ正しくデコードされません。'k' になります。) シードを渡して gen_key を呼び出すと、残りのプロセスでそのキーが使用されます。

言うまでもなく、これはあなたの目的のために機能すること、および/または安全なソリューションであることが保証されているわけではありません。実質的なセキュリティ ニーズがある場合は、セキュリティの専門家に相談する必要があります。この投稿はいかなる目的に対しても保証されておらず、その使用に起因するすべての責任は投稿者によって否認されます.

于 2013-05-16T15:04:47.567 に答える