Şifrələrin [char] üstünlüyü niyə şifrə üstündədir?

Swing-də parolu sahəsində getPassword() metodu var ( char[] getPassword() qaytarır) əvəzinə getText() metodunun yerinə (bir String qaytarır). Eləcə də, parolu idarə etmək üçün bir String istifadə etməmək təklifi ilə üzləşdim.

Şifre istifadə edərkən String təhlükəsizlik riskini yaradır? char[] istifadə etmək əlverişsizdir.

3016
16 янв. 16 yanvarda Ahamed tərəfindən təyin olundu 2012-01-16 17:20 '12 saat 17: 20-da 2012-01-16 17:20
@ 18 cavab

Strings dəyişilməzdir . Yəni, bir String yaratdıqdan sonra, başqa bir proses yaddaşını yandırarsa, heç bir yol yoxdur ( əksindən başqa ), zibil toplama başlamazdan əvvəl məlumatlardan xilas ola bilərsiniz.

Bir sıra istifadə edərək, əlbəttə ki, verildikdən sonra məlumatları silə bilərsiniz. Serialın hər hansı bir şey ilə yenidən yaza biləcəyini və zibil toplanmasından əvvəl sistemin hər hansı bir yerində parol olmayacaq.

Beləliklə, bu bir təhlükəsizlik məsələsidir, ancaq char[] istifadə edərək, yalnız təcavüzkar üçün fürsət pəncərəsini və yalnız bu xüsusi hücum tipini azaldır.

Şərhlərdə qeyd edildiyi kimi, zibil toplayıcısının köçürdüyü dizilər yaddaşdakı məlumatların effektiv surətlərini tərk edəcəkdir. Hesab edirəm ki, bu, xüsusi bir həyata keçirilir - zibil toplayıcısı bu cür bir şeydən qaçınmaq üçün bütün yaddaşları təmizləyə bilər. Hətta olsa da, char[] , hücum pəncərəsi kimi faktiki simvolları ehtiva edən müddət hələ də var.

3853
16 янв. 16 yanvarda Jon Skeet'e cavab verin 2012-01-16 17:26 '12 'də 5:26' da 2012-01-16 17:26

Buradakı digər cümlələr həqiqətən də görünsə də, başqa bir məcburi səbəb var. Müntəzəm bir String ilə təsadüfən jurnallar , monitorlar və ya digər təhlükəli yerlər üçün bir parol yazmaq ehtimalı çoxdur. char[] az həssasdır.

Bunu düşünün:

 public static void main(String[] args) { Object pw = "Password"; System.out.println("String: " + pw); pw = "Password".toCharArray(); System.out.println("Array: " + pw); } 
border=0

Yazdırın

 String: Password Array: [C@5829428e 
1114
16 янв. Cavab 16 Yanvar Konrad on123.rus verilir 2012-01-16 22:37 '12 saat 22:37 'da 2012-01-16 22:37

Rəsmi sənəddən sitat gətirmək üçün, Java kriptoqrafiya arxitekturası char[] ilə parollardan istifadə haqqında danışıqlar aparır. String (parola əsaslı şifrələmə haqqında, lakin şifrələr haqqında əlbəttə ki):

java.> bir obyektdə bir parol yığmaq və saxlamaq java.> . Lakin, burada bir ehtiyat: String Object dəyişdirilə bilməz, yəni. İstifadədən sonra String məzmununu dəyişdirməyi (dəyişdirməyi) və ya yenidən qurmağınızı təyin edən bir üsul yoxdur. Bu funksiya, String obyektlərinin istifadəçi parolası kimi həssas məlumatların saxlanması üçün istifadə edilə bilməz hala gətirir. Həmişə gizli təhlükəsizlik məlumatlarını char toplayıb saxlamalısınız.

Java 4.0 proqramlaşdırma dili üçün Təhlükəsiz kodlaşdırma Kılavuzunun 2-2 əlavəsi də oxşar bir şey deyir (ilk növbədə jurnalistika kontekstindədir):

Təlimat 2-2: Yüksək həssas məlumatları qeydiyyatdan keçirməyin.

Sosial təhlükəsizlik nömrələri (SSN) və parollar kimi bəzi məlumatlar çox həssasdır. Bu məlumat zəruri olduğundan və mümkünsə hətta administratorlardan daha uzun saxlanılmamalıdır. Məsələn, faylları qeyd etmək üçün göndərilməməlidir və axtarış zamanı aşkar olunmamalıdır. Bəzi keçidlər dəyişən məlumat strukturlarında saxlana bilər, məsələn, array seriyaları və istifadədən dərhal sonra silinir. Data strukturlarının təmizlənməsi, tipli Java işləmə sistemlərində performansın azalmasına səbəb olur, obyektlər yaddaşda proqramçıya şəffaf şəkildə hərəkət edirlər.

Bu təlimatda ayrıca məlumatların semantik məlumatları olmayan aşağı səviyyəli kitabxanaların tətbiqi və istifadəsi ilə bağlı təsiri vardır. Bir nümunə olaraq, aşağı səviyyəli kitabxanada ayrıştırma işlədiyi mətni qeyd edə bilər. Ərizə SSN ilə kitabxananı təhlil edə bilər. Bu, SSN-nin administratorlara giriş faylları ilə əldə edilə biləcəyi bir vəziyyət yaradır.

634
17 янв. Cavab Bruno tərəfindən 17 yanvarda verilir . 2012-01-17 06:20 '12 at 6:20 'da 2012-01-17 06:20

Karakter dizilerini ( char[] ) istifadə edildikdən sonra hər bir xarakterin sıfıra bərabər olmasına baxmayaraq təmizlənə bilər. Birisi görünüşü yaddaşda görsəydilər, parol düz mətndə görürlər, əgər strings istifadə olunur, amma char[] edilərsə, char[] məlumatları təmizlədikdən sonra parol qorunur.

319
16 янв. Alfx tərəfindən verilən cavab 16 yanvar 2012-01-16 17:27 '12 at 17:27 2012-01-16 17:27

Bəzi insanlar parolunuzu artıq ehtiyacınız olmadığı anda saxlamaq üçün istifadə olunan yaddaşın üzərində yazmaq lazımdır. Bu, təcavüzkarın sistemdən parolunuzu oxuması və saldırganın bunun üçün JVM yaddaşını tutmaq üçün zaten erişim gereksinimini tamamen görmezden gelmesini engeller. Belə girişi olan bir təcavüzkar, əsas hadisələrinizi tamamilə yararsız hala gətirə bilər (AFAIK, mən səhv edərsən məni düzəltməyin).

Yeniləmə

Şərhlərin sayəsində mən cavabımı yeniləməliyəm. Şifrənin sabit diskə düşə biləcəyi vaxt azaldığından, bu (çox) kiçik təhlükəsizlik təkmilləşdirilməsi əlavə edə biləcək iki haldır. Lakin, əksər hallarda bu çox çox düşünürəm.

  • Hedef sisteminiz zəif konfiqurasiya ola bilər və ya onu qəbul etməlisiniz və əsas çöküntülər haqqında paranoyə olmalıdır (sistemlər bir administrator tərəfindən idarə edilmirsə etibarlı ola bilər).
  • Təcavüzkarın TrueCrypt (dayandırılmış), VeraCrypt , və ya CipherShed kimi funksiyalardan istifadə etməsinə imkan yaradan zaman proqramınızın sızması qarşısını almaq üçün çox paranoid olmalıdır.

Mümkünsə, əsas boşalma və disk yaddaş fayllarını silmək bütün problemləri həll edəcəkdir. Bununla yanaşı, inzibati məsuliyyət tələb edir və funksionallığı azalda bilər (istifadə etmək üçün yaddaş azdır) və RAM-i işləyən sistemdən çıxarmaq hələ də ciddi narahatlıq doğurur.

194
16 янв. cavab josefx tərəfindən verilir 2012-01-16 17:32 '12 at 17:32 2012-01-16 17:32
  • Şifrəni düz mətndə saxlayarsanız , sətirlər dəyişməzdirsə , çöp toplayıcısı onu təmizləməyincə yaddaşda mövcud olacaq və simli təkrar istifadə üçün simli hovuzda istifadə edildikdən sonra ehtimalı yaddaşda qalacaqdır uzun müddət təhlükə yaradan təhlükə yaradır. Bir yaddaş dumpinə çıxışı olan hər kəs açıq-aşkar bir mətndə parol tapa bilər.
  • getPassword() metodu ilə istifadə edilən Java məsləhətləri , [] metodu və parolanı təhlükəsizliyin səbəbini göstərən mətn şəklində qaytaran köhnəlmiş getText() funksiyasını qaytaran JPasswordField.
  • toString () həmişə bir günlük və ya konsol faylında düz mətni yazma riski var, ancaq Array istifadə etsəniz, dizinin məzmununu çap etməyəcəksiniz və onun yaddaşı basılır.

     String strPwd = "passwd"; char[] charPwd = new char[]{'p','a','s','s','w','d'}; System.out.println("String password: " + strPwd ); System.out.println("Character password: " + charPwd ); 

    Parolu şifrə: passwd

    Karakter parolası: [C 110b2345

Son düşüncələr: char [] istifadə etməsi yalnız kifayət deyil, məzmunu daha təhlükəsiz olmaq üçün silmək lazımdır. Doğrudan mətn əvəzinə hasil edilən və ya şifrələnmiş parol ilə işləmək və autentifikasiya başa çatdıqdan sonra onu yaddaşdan silmək məsləhətdir.

125
27 дек. Cavab Sruyan Kumar Gülla 27 dekabrda verilir. 2012-12-27 23:22 '12 saat 11:22 pm 2012-12-27 23:22

Mən bunun doğru cümlə olduğunu düşünmürəm, amma bu səbəbdən ən azı təxmin edə bilərik.

Mən motivasiya edirəm ki, bir şifrənin bütün izlərini yaddaşdan və istifadə etdikdən sonra güvən ilə tez və etibarlı bir şəkildə silmək mümkündür. char[] sətrin hər elementini boş və ya tam bir şeylə yaza bilərsiniz. String daxili dəyərini bu şəkildə düzəldə bilməzsiniz.

Amma bu yaxşı bir cavab deyil; niyə sadəcə char[] və ya String istinad edilmir ki, yox? Sonra təhlükəsizlik məsələsi yoxdur. Amma əslində String obyektləri intern() təyin edilmiş və daimi hovuzda saxlanıla bilər. Mən char[] istifadə edərək, bu funksiyanı inkar edirəm.

76
16 янв. cavab 16 yanvarda Sean Owen tərəfindən verilir . 2012-01-16 17:27 '12 at 17:27 2012-01-16 17:27

Cavab artıq verilmişdir, amma standart Java kitabxanaları ilə yaxınlarda aşkarladığım bir problemi paylaşmaq istərdim. İndi çox diqqətlə char[] parol şifrələrini (əlbəttə ki, yaxşıdır) əvəz etsələr də, digər mühüm kritik məlumatlar yaddaşdan silinməsinə baxmayaraq göz ardı edilir.

Mən, məsələn, PrivateKey sinfi deməkdir . RSA xüsusi düyməsini PKCS # 12 faylından yüklədiyiniz bir ssenari nəzərdən keçirin. İndi, bu halda, əsas faylya fiziki giriş düzgün bir şəkildə məhdudlaşdırılmadan parol koklama öz-özünə kömək etmir. Bir təcavüzkar kimi, birbaşa əsas deyil, şifrəni alsanız, daha yaxşı olacaqsınız. İstədiyiniz məlumatlar bir çoxunu buraxa bilər, əsas dökümlər, debugger seansları və ya paging faylları yalnız bir neçə nümunədir.

PrivateKey , fərdi məlumatları PrivateKey dən yaddaşdan təmizləmək üçün imkan verəcək heç bir şey yoxdur, çünki müvafiq məlumatları meydana gətirən baytların silməsinə icazə verən API yoxdur.

Bu vəziyyət pis vəziyyətdir, çünki bu sənəd bu vəziyyətin potensial olaraq necə istifadə ediləcəyini təsvir edir.

OpenSSL kitabxanası, məsələn, gizli açarları buraxmadan əvvəl yaddaşın kritik sahələrini yazır. Java çöp topladığı üçün, Java düymələri üçün fərdi məlumatları təmizləmək və etibarsızlaşdırmaq üçün açıq üsula ehtiyacımız var, ancaq istifadə edildikdən dərhal sonra tətbiq edilməlidir.

61
19 янв. cavab 19 Yanvar verildi 2012-01-19 22:39 '12 at 10:39 pm 2012-01-19 22:39

John Skeet iddia etdiyi kimi, düşüncədən başqa bir yol yoxdur.

Lakin, əksiniz sizin üçün bir seçimdirsə, bunu edə bilərsiniz.

 public static void main(String[] args) { System.out.println("please enter a password"); // don't actually do this, this is an example only. Scanner in = new Scanner(System.in); String password = in.nextLine(); usePassword(password); clearString(password); System.out.println("password: '" + password + "'"); } private static void usePassword(String password) { } private static void clearString(String password) { try { Field value = String.class.getDeclaredField("value"); value.setAccessible(true); char[] chars = (char[]) value.get(password); Arrays.fill(chars, '*'); } catch (Exception e) { throw new AssertionError(e); } } 

başlanğıcda

 please enter a password hello world password: '***********' 

Qeyd: String char [] GC loopunun bir hissəsi kimi kopyalandıysa əvvəlki surətin yaddaşda olduğu bir şans var.

Bu köhnə kopya yığın döküntüsündə görünməyəcək, amma prosesin xammal yaddaşına birbaşa çıxışınız varsa, onu görə bilərsiniz. Ümumiyyətlə, istənilən istifadəçi tərəfindən əldə edilməməlidir.

44
08 июля '15 в 12:26 2015-07-08 12:26 cavab Peter Lawrey tərəfindən 08 İyul, '15 'də saat 12:26' də verilir

Düzenle: Bir il təhlükəsizlik tədqiqatından sonra bu cavana geri döndüyünüzdə, bu məntiqi mətn parollarını müqayisə edəcəyiniz bəzi xoşagəlməz nəticələrə gətirib çıxardığını başa düşürəm. Xahiş edirik etməyin. Təhlükəsiz birtərəfli duz tullantılarını və çox sayda təkrar istifadə edin . Kitabxanadan necə istifadə edəcəyinizi düşünün: başa düşmək çətindir!

Orijinal cavab: String.equals () qısa qapanış qiymətləndirməsindən istifadə edir və buna görə də müvəqqəti hücuma məruz qalır? Bu qeyri-mümkün ola bilər, amma nəzəri olaraq, simvolun düzgün ardıcıllığını müəyyən etmək üçün vaxtla parolla müqayisə edə bilərsiniz.

 public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; // Quits here if Strings are different lengths. if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; // Quits here at first different character. while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false; } 

Bir neçə vaxtlama qaynağı:

37
08 апр. Cavab Qrafik Teorisi Apr 08 ilə verilir 2015-04-08 03:04 '15 at 03:04 2015-04-08 03:04

Bunlar bütün səbəblərdir, şifrənin yerinə String yerinə char [] array seçməlisiniz.

Şifrəni düz mətndə saxladığınız halda, strings Java-da dəyişməz olduğundan, Çöp toplayıcısı onu təmizləməyincə və String yenidən istifadəsi üçün String havuzunda istifadə edildikdən sonra olduqca yüksək ehtimalı var uzun müddətdir ki, o, təhlükəsizlik riskini yaradan yaddaşda qalacaq.

Yaddaş dökümü ilə əlaqəli olan hər kəs açıq bir mətndə parol tapa bildiyindən, həmişə düz mətni əvəzinə şifrəli bir parol istifadə etməlisiniz. Dizgeler dəyişməz olduğundan, strings məzmununu dəyişdirmək mümkün deyil, çünki hər hansı bir dəyişiklik yeni bir simli yaradır və char [] istifadə etsən, hələ də bütün elementləri boş və ya null olaraq təyin edə bilərsiniz. Beləliklə, simvol bir sıra parol saxlanılması parol oğurluq təhlükəsizliyi riskini aydınlaşdırır.

Java özü, təhlükəsizlik məsələlərini göstərən açıq mətndə parolları qaytaran köhnəlmiş getText () metodunun yerinə char [] funksiyasını qaytaran JPasswordField getPassword () metodundan istifadə etməyi tövsiyə edir. Java qrupunun tövsiyələrini yerinə yetirmək və standartlara riayət etmək və onlara qarşı getməmək yaxşıdır.

3. Bir String istifadə edərkən, hər hansı bir log və ya konsol faylında düz mətni yazmaq təhlükəsi var, ancaq Array istifadə edərsə, dizinin məzmununu çap etməyəcəksiniz və yerinə onun yeri yazdırılacaq. Bu əsl səbəb olmasa da, hələ də məntiqlidir.

 String strPassword="Unknown"; char[] charPassword= new char[]{'U','n','k','w','o','n'}; System.out.println("String password: " + strPassword); System.out.println("Character password: " + charPassword); String password: Unknown Character password: [C@110b053 

Bu bloga keçid. Bu kömək edir.

36
08 мая '14 в 13:17 2014-05-08 13:17 Cavab 08 May 'da 13:17' də İnsanlığa verildi 2014-05-08 13:17

İstifadədən sonra onu əllə təmizləməsəniz, char array sizə bir String verir və heç kim bunu görmədim. Buna görə, mənim üçün, üstün char char [] vs String biraz abartılıdır.

Burada geniş yayılmış Bahar təhlükəsizliyi kitabxanasına nəzər salın və özünüzdən soruşun: Bahar Təhlükəsizlik uşaqları qeyri-səlahiyyətli və ya [] şifrələri yalnız çox mənalı deyil. Bəzi pis xaker yaddaşınızın yaddaşını tutduqda, onları gizlətmək üçün kompleks yollardan istifadə etsəniz də, bütün parolları aldığından əmin olun.

Bununla belə, Java hər zaman dəyişir və Java 8 simli deduplication funksiyası kimi bəzi qorxudan xüsusiyyətlər sizin məlumatınız olmadan String obyektlərini təyin edə bilər. Ancaq bu fərqli söhbətlərdir.

33
24 янв. Cavab Oleq Mikheev 24 yanvar verilir 2015-01-24 10:43 '15 at 10:43 2015-01-24 10:43

Strings dəyişməzdir və yaradıldıqdan sonra dəyişdirilə bilməz. Parolu bir parol olaraq yaratmaq yığındakı və ya simli hovuzdakı parolun qalıqlığına səbəb olacaq. İndi əgər kimsə bir Java-prosesinin yığınları götürsə və diqqətlə onu yoxlayırsa, parolları təxmin edə bilər. Əlbəttə ki, bu istifadə edilməmiş xəttlər zibil toplayacaq, amma bu GC-nin başladığı vaxtdan asılıdır.

Digər tərəfdən, [] dəyişiklikləri autentifikasiya edildikdən sonra dəyişir, siz onları M-ə ya da əks-sədaqalar kimi hər hansı bir xarakterlə yaza bilərsiniz. İndi bir çox yığın çəksə də, hazırda istifadə edilməyən parol əldə edə bilməz. Bu, bir obyektin məzmununu özünüzdə və ya bir GC-nin tamamlanmasını gözləməzdən əvvəl təmizləmək mənasında daha çox nəzarət verir.

29
28 июля '15 в 13:46 2015-07-28 13:46 Cavab Geek 28 iyul '13 'də 13:46' də verilir 2015-07-28 13:46

Qısa və sadə cavab isə char[] bilər və String obyektləri olmur.

Java'da Strings dəyişməz obyektlərdir. Məhz buna görə yaradılışdan sonra dəyişdirə bilməzlər və buna görə də onların məzmununu yaddaşdan çıxarmaq üçün yeganə yol zibil ilə yığmaqdır. Bu, yalnız obyektin azad etdiyi yaddaşın üzərində yazıla bilər və məlumatlar yox olacaq.

İndi Java'da zibil toplanması hər hansı bir zəmanət aralığında baş vermir. Beləliklə, String uzun müddət yaddaşda saxlanıla bilər və əgər proses bu müddət ərzində uğursuz olarsa, simli məzmun yaddaş dökümü və ya bir növ gündəmdə ola bilər.

Bir xarakterli array istifadə edərək, şifrəni oxuya bilərsiniz, mümkün qədər tez çıxa bilərsiniz və dərhal məzmunu dəyişə bilərsiniz.

17
09 дек. Cavab Pritam Banerjee 09 dekabrda verilir. 2016-12-09 22:02 '16 saat 10:02 'da 2016-12-09 22:02

1) Şifrəni Java-da dəyişməz olduğundan, parolu düz mətn olaraq saxladığınız halda, çöp toplayıcısı onu təmizləyənə qədər yaddaşda mövcud olacaq və String, String havuzunda təkrar istifadə üçün istifadə edildikdən sonra çox yüksək ehtimalı var uzun müddətdir ki, bir təhlükəsizlik riski yaradan yaddaşda qalacaq. Yaddaş dökümü ilə əlaqəli olan hər kəs açıq bir mətndə parol tapa bilər və bu səbəblə həmişə düz mətndən daha şifrəli bir parol istifadə etməlisiniz. Strings dəyişməz olduğundan, strings məzmununu dəyişdirə bilməzsiniz, çünki hər hansı bir dəyişiklik yeni bir simli yaradır və siz [] funksiyası varsa, hələ də bütün elementi boş və ya null olmalıdır. Beləliklə, bir simvolu bir parol saxlayaraq parol oğurluq riskini azaldır.

2) Java özü, təhlükəsizliyin səbəbini göstərən açıq mətndə parolunu qaytaran char [] və köhnəlmiş getText () metodunu qaytaran JPasswordField getPassword () metodundan istifadə etməyi tövsiyə edir. Java qrupunun məsləhətinə riayət etmək və standarta sadiq olmaq və ona qarşı çıxmaq yaxşıdır.

16
07 сент. Cavab Neeraj Gahlawat'a verildi 07 Sep 2017-09-07 13:47 '17 saat 13:47 'də 2017-09-07 13:47

Dize dəyişməz və satır havuzuna gedir. Yazdıqdan sonra bu yazı yazıla bilməz.

char[] parol istifadə etdikdən sonra üzərində yazmaq lazımdır ki, bir sıra və bunun necə edilməsi lazımdır:

 char[] passw = request.getPassword().toCharArray() if (comparePasswords(dbPassword, passw) { allowUser = true; cleanPassword(passw); cleanPassword(dbPassword); passw=null; } private static void cleanPassword (char[] pass) { for (char ch: pass) { ch = '0'; } } 

Один сценарий, в котором злоумышленник может использовать его, - это crashdump - когда JVM падает и генерирует дамп памяти - вы сможете увидеть пароль.

Это не обязательно злонамеренный внешний злоумышленник. Это может быть пользователь службы поддержки, который имеет доступ к серверу для целей мониторинга. Он мог заглянуть в аварийный диск и найти пароли.

14
ответ дан ACV 26 апр. '18 в 1:39 2018-04-26 01:39

Строка в java неизменна. Поэтому всякий раз, когда создается строка, она остается в памяти до тех пор, пока не будет собрана мусор. Поэтому любой, кто имеет доступ к памяти, может прочитать значение строки.
Если значение строки будет изменено, это приведет к созданию новой строки. Таким образом, как исходное значение, так и измененное значение остаются в памяти, пока не будет собран мусор.

С помощью массива символов содержимое массива может быть изменено или удалено после того, как будет применена цель пароля. Исходное содержимое массива не будет найдено в памяти после его модификации и даже до того, как будет запущена сборка мусора.

Из-за проблемы безопасности лучше хранить пароль в виде массива символов.

12
ответ дан Saathvik 28 июля '17 в 9:33 2017-07-28 09:33

Использование пароля в String или Char [] всегда является спорным, потому что оба подхода имеют свою собственную полезность и недостаток. Это зависит от потребности, которую пользователь ожидает выполнить. Ниже строки могут помочь лучше понять, когда использовать этот контейнер: поскольку String в java неизменен, всякий раз, когда кто-то пытается манипулировать вашей строкой, он создает новый Object и существующий остается без изменений. Это можно рассматривать как преимущество для хранения пароля как String, но с другой стороны. Объект String остается в памяти даже после использования. Так что, если кто-нибудь получит место в памяти, вы сможете легко отслеживать свой пароль, хранящийся в этом месте. Придя к Char [], который изменен, но он имеет преимущество, что после использования программист может Explicilty очистить массив или переопределить значения. Так что после того, как он не используется, он очищается, и никто не может знать о том, что вы сохранили.

Исходя из вышеприведенных обстоятельств, можно получить идею о том, следует ли идти со String или Char [] по их требованию.

Təşəkkür edirik.

0
ответ дан Neeraj 03 дек. '18 в 9:31 2018-12-03 09:31

Другие вопросы по меткам или Задайте вопрос